Seite 5 von 5
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 16:41
von DaMutz
die Linie Klasse habe ich einmal geschrieben. Ich habe dazu noch eine Frage. Wie würdet ihr die __eq__-Methode schreiben.
V1:
Code: Alles auswählen
class Line(object):
def __init__(self, fid, points):
self.fid = fid
self.points = points
def __eq__(self, other):
return all(any(s == o for o in other.points) for s in self.points)
V2:
Code: Alles auswählen
return any(self.points[0] == o for o in other.points) and any(self.points[1] == o for o in other.points)
V3:
Code: Alles auswählen
return (self.points[0] == other.points[0] or self.points[0] == other.points[1])
and (self.points[1] == other.points[0] or self.points[1] == other.points[1])
@Michi_J: BlackJack hat ja alle Funktionen zum Umwandeln der Daten schon beschrieben, man muss sie nur noch implementieren...
create_points würde in etwa so aussehen:
Code: Alles auswählen
def create_points(data):
points = {}
for point_data in data:
fid = point_data[1][0][0]
points[fid] = Point(fid, point_data[1][0][1])
fid = point_data[1][1][0]
points[fid] = Point(fid, point_data[1][1][1])
return points
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 16:51
von BlackJack
Ich hätte die `Line`-Klasse wohl so implementiert.
Code: Alles auswählen
class Line(object):
def __init__(self, fid, points):
self.fid = fid
self.points = tuple(points)
def __cmp__(self, other):
return cmp(sorted(self.points), sorted(other.points))
def __hash__(self):
return hash(tuple(sorted(self.points)))
Wenn man `__eq__` oder `__cmp__` implementiert, sollte man auch `__hash__` implementieren. Falls einem da nichts sinnvolles einfällt, gerne auch als ``raise TypeError('unhashable')``. Dann kracht's wenigstens richtig und versagt nicht auf eher subtile Weise, die einem vielleicht nicht sofort auffällt, wenn man die Objekte in `dict()`\s oder `set()`\s verwendet.
Falls das mit dem Sortieren ein messbares Laufzeitproblem wird, könnte man einen Sortier- und Hash-Schlüssel schon beim erstellen des Objekts anlegen.
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 20:27
von frabron
Auch auf die Gefahr hin, mich zu
wiederholen: Für solche Anwendungen gibt es bereits
fertige Implementierungen
Code: Alles auswählen
>>> from shapely.geometry import Polygon
>>> p1 = Polygon([(0,0),(0,2),(1,1)])
>>> print p1.area
1.0
>>> p2 = Polygon([(0,0),(0,2),(-1,-1)])
>>> print p2.area
1.0
>>> p1.touches(p2)
True
>>>
Die
GEOS Bibliothek, auf der Shapely aufbaut, ist eine sehr ausgereifte Software, die weit verbreitet in OpenSource GIS Anwendugen ist. Gerade hier, wo es sich doch um eine imho sehr klassische GIS-Problematik handelt, würde sich die Nutzung ja anbieten ...
Hier noch ein Beispiel, wie man die Verwandschaft zwischen zwei Geometrien herausfinden kann. Touches ist auch True, wenn sich nur die Spitzen berühren
Code: Alles auswählen
>>> p3 = Polygon([(0,2),(0,4),(3,1)])
>>> p2.touches(p3)
True
>>> p1.touches(p3)
True
intersection gibt die Art der Verwandschaft preis:
Code: Alles auswählen
>>> i = p1.intersection(p2)
>>> print i
LINESTRING (0.0000000000000000 0.0000000000000000, 0.0000000000000000 2.0000000000000000)
>>> j = p2.intersection(p3)
>>> print j
POINT (0.0000000000000000 2.0000000000000000)
Oder wenn man auf Schmerzen steht die
de-9im Matrix
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 08:13
von Michi_J
Wow, da sind wohl echte Profis am Werk, die ihre Sache verstehen

Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 08:18
von Michi_J
Vielen Dank für all eure Bemühungen und Beiträge!
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 08:22
von Michi_J
Auf meinem harten und steinigen Weg dorthin Python in seinen Ansätzen zu verstehen - mehr wage ich auch gar nicht - ist mir bei meiner Sortieraufgabe ein weiteres Problem aufgefallen:
Ich habe eine Liste L = ([a,b], [c,d], [b,a], [d,c]) und aus der möchte ich die Liste L1=([a,b], [c,d]) erzeugen, wo also die "umgedrehten" Einträge nicht mehr vorhanden sind.
Kann mir hier vielleicht auch jemand helfen?
Danke!
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 09:28
von frabron
Was sind denn a,b,c,d für Datentypen? Zahlen oder Strings oder ...
Im allgemeinen könntest du für deinen Datentyp, wenn es eine eigene Klasse ist, die
__hash__ Methode implementieren und dann ein set aus der Liste machen. Obwohl - verrrate erst einmal, was du da für Daten in der Liste hast
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 09:29
von BlackJack
@Michi_J: Das kommt auf die Typen an, die `a`, `b`, usw. haben. Wenn die sortier- und hash-bar sind, könnte man die Einträge in `L` in ein sortiertes Tupel umwandeln und mittels eines `set()`\s Buch darüber führen ob man die Werte schon einmal gesehen hat. Und nur dann `L1` hinzufügen, wenn das nicht der Fall war.
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 09:31
von Michi_J
a, b, c, d sind Zahlen
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 09:32
von Michi_J
z.B. Liste = [[1,17], [2,1], [17,1], [1,2]]
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 11:04
von Michi_J
und gleich noch eine Frage hierzu: wenn ich eine Liste hab, die folgendermaßen aufgebaut ist:
Liste = [[1, [X1, Y1, Z1]], [2, [X2, Y2, Z2], [3, [X1, Y1, Z1], [4, [X3, Y3, Z3]]
das heißt, der Eintrag mit der ID = 1 und mit ID = 3 haben dieselben Koordinaten X1, Y1, Z1. Nun möchte ich die ID=3 durch ID=1 ersetzen, da sie ja beide die gleichen Koordinaten haben, sodass meine Liste also folgendermaßen aussieht:
Liste = [[1, [X1, Y1, Z1]], [2, [X2, Y2, Z2], [1, [X1, Y1, Z1], [4, [X3, Y3, Z3]]
vielleicht hat hierzu auch wer eine Idee. Danke auf alle Fälle an alle und für alles! Ohne euch wärs etwas schwer!
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Mittwoch 1. September 2010, 13:44
von frabron
Und wann hörst du auf, mit diesen verschachtelten Listen zu arbeiten? Die ganze letzte Seite ging doch darum, dass du dir endlich vernünftige Datentypen für deine Datenstruktur ausdenkst. Du wirst so _nicht_ glücklich werden :K
Das hier jetzt noch als Denkanstoss ...
Code: Alles auswählen
from shapely.geometry import Point
class Node(object):
def __init__(self, id, geom):
self.id = id
self.geom = geom
p1 = Node(1, Point(1,1,1))
p2 = Node(2, Point(2,2,2))
p3 = Node(3, Point(1,1,1))
p4 = Node(4, Point(4,4,4))
for pa in (p1,p2,p3,p4):
for pb in (p1,p2,p3,p4):
print pa.id, pb.id, pa.geom.equals(pb.geom)
Code: Alles auswählen
1 1 True
1 2 False
1 3 True
1 4 False
2 1 False
2 2 True
2 3 False
2 4 False
3 1 True
3 2 False
3 3 True
3 4 False
4 1 False
4 2 False
4 3 False
4 4 True
Das darf man so nicht 1:1 übernehmen, sondern soll nur Ideen wecken, wie du an die Sache herangehen könntest
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Freitag 3. September 2010, 08:29
von Michi_J
@frabron: Danke für deinen Denkanstoß. Das "Abwenden" von verschachtelten Listen hin zu Objektorientierung ist für mich nicht so ganz einfach, da sehr neu. Ihr seit aber alle sehr bemüht um mich, muss ich feststellen und deshalb denke ich, dass ichs auch hinbekommen könnte.
Für meine "verschachtelte" Version gibt es keine Lösung? Oder funktioniert das nur mit Klassen und Funktionen?
Danke auf alle Fälle nochmals für eure Hilfen!
Michi
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Freitag 3. September 2010, 09:24
von bwbg
Sicher ist es möglich, die Listen in irgendeiner Weise zu verwursten. Es macht aber keinen Sinn, da man das mittels OOP wesentlich übersichtlicher und vor allem nachvollziehbarer gestalten kann (wie man Dir auch schon auf den letzten 7 (?) Thread-Seiten hat versucht zu vermitteln). Ich nehme mal nicht an, dass sich jemand unbezahlt, freiwillig, unnötigerweise die Hirnzellen verdreht, nur damit Dein Listenkrampf funktioniert.
Es ist jetzt der Zeitpunkt gekommen, das Thema ruhen zu lassen, ein Paket Kaffee zu kaufen, die Wasserrechnung zu bezahlen und sich einige Stunden intensivst mit der OOP zu beschäftigen - und zwar nicht anhand Deines aktuellen Problems. Im Anschluss daran (so nach ein oder zwei Wochen) darfst du diesen Thread dann wiederbeleben.
Grüße ... Heiko