Seite 4 von 5
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 09:52
von BlackJack
@Michi_J: Bist Du sicher das Dein Problem nicht schon irgendwer gelöst hat? Das klingt verdächtig nach
triangle strips, die man zum Beispiel auch bei OpenGL erzeugt um zusammenhängende Dreiecke effizient zu speichern.
Ansonsten müsstest Du Dir überlegen welche Attribute und Eigenschaften Punkte, Linien, und Dreiecke als Objekte minimal haben müssten. Erst einmal nur um sie zu erstellen und dann um die Dreiecke zu einem Objektgraphen zu verbinden.
Ich würde sie als Wertobjekte implementieren, mit entsprechenden `__cmp__`- und `__hash__`-Implementierungen um sie als Schlüssel in Dictionaries bzw. Elemente in `set()`\s verwenden zu können.
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 11:54
von Michi_J
Vielleicht folgendermaßen:
Objekt: Dreieck --> besteht aus Linien und Linien aus Punkten (Punkte sind definiert über XYZ)
Eigenschaft: 2 Dreiecke sind benachbart, wenn sie sich 1 Linie teilen
???
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 11:56
von Michi_J
Tut mir leid, dass ich so hilflos bin, aber ich weiß es wirklich nicht, wie ich vorgehen soll...
Und wie gesagt, ich bedanke mich nochmals bei jedem, der mir hilft.
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 12:44
von BlackJack
@Michi_J: Na dann fang doch einfach mal mit dem kleinsten Baustein an. Schreib eine `Point`-Klasse und dann eine Funktion die aus den Daten Punkt-Objekte erstellt. Und dann eine `Line`-Klasse, die aus den Daten und den Punkt-Objekten Linien-Objekte erstellt. Und dann… ich denke das Prinzip sollte klar sein.
Re: Durchlauf durch Liste und Vergleich der Einträge
Verfasst: Dienstag 31. August 2010, 14:31
von Michi_J
hmmm...
Kling für mich einfacher als es ist. Aber danke

!
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