Seite 2 von 2

Verfasst: Dienstag 18. August 2009, 00:33
von lunar
@Yogi: Es geht nicht um Geschwindigkeit, sondern um Wartbarkeit und Eleganz. "xrange(len(liste))" tut man einfach nicht ;), wenn man auf Listenelemente zugreifen will. Die zusätzlichen Indirektionen durch die ganzen Index-Zugriffe sorgen nur für Verwirrung. "for item in liste" oder "for index, item in enumerate(liste)" (wenn der Index benötigt wird) sind die idiomatischen Wege zur Iteration über eine Liste.

Verfasst: Dienstag 18. August 2009, 00:35
von Yogi
lunar hat geschrieben:@Yogi: Lies Dir doch bitte die Dokumentation zu "sorted()" oder "list.sort()" durch. Die Funktion sortiert natürlich nicht, aber das soll sie auch gar nicht ("operator.itemgetter()" sortiert auch nicht). Die "key"-Funktion wird vom Sortieralgorithmus einmal für jedes Element aufgerufen, um für dieses Element ein sortierbares Datum zu erzeugen. Die Funktion erhält also ein einzelnes Listenelement, nimmt vom diesem die Elemente 0, 2 und 1, konvertiert sind in Kleinschreibung und gibt das so erzeugte Tupel zurück. Dieses Tupel wird dann vom Sortieralgorithmus verwendet, um die eigentliche Liste zu sortieren.
Bin zu platt, hast ja vollkommen recht. Gibt aber trottzdem einen Fehler. Der Aufruf ist doch so richtig, oder?

Code: Alles auswählen

ren.sort(key=sortable_tuple(ren))

Verfasst: Dienstag 18. August 2009, 00:36
von lunar
Nein. Du sollest die Funktion selbst und nicht ihren Rückgabewert übergeben:

Code: Alles auswählen

ren.sort(key=sortable_tuple))

Verfasst: Dienstag 18. August 2009, 00:39
von Yogi
lunar hat geschrieben:@Yogi: Es geht nicht um Geschwindigkeit, sondern um Wartbarkeit und Eleganz. "xrange(len(liste))" tut man einfach nicht ;), wenn man auf Listenelemente zugreifen will. Die zusätzlichen Indirektionen durch die ganzen Index-Zugriffe sorgen nur für Verwirrung. "for item in liste" oder "for index, item in enumerate(liste)" (wenn der Index benötigt wird) sind die idiomatischen Wege zur Iteration über eine Liste.
Gib ich dir ja vollkommen recht, werde mich bessern, versprochen!... aber nicht mehr jetzt, müde, muss schlafen, muss morgen fit sein, fit sein, und elegant...oje...

Bis dahin schon mal einen großen Dank. Wenn alles läuft versuch ichs auf elegegant, obwohl da Python gerne verstecken spielt. Python lernen ist ja einfach, Python lernen elegant, schawär.... Gnacht

Verfasst: Dienstag 18. August 2009, 00:44
von Yogi
lunar hat geschrieben:Nein. Du sollest die Funktion selbst und nicht ihren Rückgabewert übergeben:

Code: Alles auswählen

ren.sort(key=sortable_tuple))
Ahhhhhh und dann noch diese kleine Änderung, weil die restlichen Sortierfelder Floats sind...

Code: Alles auswählen

def sortable_tuple(item):
    return tuple(item[1].lower())
Hast recht, viel schöner und sauberer. Thx! Morgen mach ich dann den Rest auch schöner und elegant....

Verfasst: Dienstag 18. August 2009, 09:39
von EyDu
So ein kleiner Hinweis:

Code: Alles auswählen

>>> tuple("abcd")
('a', 'b', 'c', 'd')

Verfasst: Dienstag 18. August 2009, 12:38
von Yogi
EyDu hat geschrieben:So ein kleiner Hinweis:

Code: Alles auswählen

>>> tuple("abcd")
('a', 'b', 'c', 'd')
@EyDu: Ich weiss zwar nicht viel, aber das wusste ich!

@luna: Voll verschlafen heute, von meiner Tochter geweckt :shock:

So muss es jetzt lauten und es klappt. Heute abend wirds noch mal elegant gemacht ;)

Code: Alles auswählen

def sortable_tuple(item):
    return tuple(str(item[i]).lower() for i in (1, 3, 2))

Verfasst: Dienstag 18. August 2009, 12:51
von EyDu
Die beiden anderen Werte waren doch Floats, oder?

Code: Alles auswählen

>>> str(2.0)<str(10.0)
False
In deinem Fall reicht dann auch das hier:

Code: Alles auswählen

def sortable_tuple(item):
    return item[1].lower(), item[3], item[2]

Verfasst: Mittwoch 19. August 2009, 00:01
von Yogi
@EyDu: Also bei mir (Python 2.51) kommt bei

Code: Alles auswählen

str(2.0) < str(5.0)
True
Und ich halte die andere Lösung für flexibler und ...!! eleganter !! ;)

Aber recht hattest du mit zip, viel besser..

Code: Alles auswählen

ren = zip(nodeIDs, filenames, coordsX, coordsY, headlines, nodelabels, xcomments, sources) 
Muss man halt nur wissen als Nicht-Pythonier, kann ja nicht die ganze Referenz durchlesen und merken vor dem ersten Spatenstich...

Den Rest des Codes zeige ich besser nicht (Elementtree), sonst kommt noch der Exorzist :twisted:

Verfasst: Mittwoch 19. August 2009, 00:15
von cofi
Yogi hat geschrieben:@EyDu: Also bei mir (Python 2.51) kommt bei

Code: Alles auswählen

str(2.0) < str(5.0)
True
Ist das Absicht, dass du nicht EyDus Fall uebernimmst? Jedenfalls hat er recht, denn Strings werden lexikalisch verglichen und es gilt nunmal nicht, dass "2" < "1" (und das ist unabhaengig von der Version).
Yogi hat geschrieben:Den Rest des Codes zeige ich besser nicht (Elementtree), sonst kommt noch der Exorzist :twisted:
Na wenn du denkst, dass der kommt, solltest du den zeigen, sonst kommt er unerwartet in der Nacht - oder am Morgen vor dem ersten Kaffee :twisted:.

Verfasst: Mittwoch 19. August 2009, 00:18
von lunar
cofi hat geschrieben:Jedenfalls hat er recht, denn Strings werden lexikalisch verglichen und es gilt nunmal nicht, dass "2" < "1" (und das ist unabhaengig von der Version).
Ich wäre aber auch sehr überrascht, wenn das bei Zahlen gelten würde ;)

Verfasst: Mittwoch 19. August 2009, 01:24
von EyDu
Yogi hat geschrieben:Und ich halte die andere Lösung für flexibler und ...!! eleganter !! ;)
Gut, wenn dir das wichtiger ist als korrekt ;-)

Du solltest unbedingt aus deinen geschätzten viertausend Listen eine machen, wobei jeder Eintrag alle Elemente zu einem Index enthält. Du baust gerade sehr umständlich Objekte nach.

Verfasst: Mittwoch 19. August 2009, 08:58
von Yogi
Nene, ich hab nur die Listen die ich hier aufgeführt habe. Und da das Programm auch recht kurz ist, <140 Zeilen, hoffe und denke ich, dass ich auf die Schnelle so davon komme, zumindest kann ich meinen Code gut lesen.

Kann aber auch sein, dass ich später noch einmal versuchen werde, das ganze pythonesker umzusetzen.

Aber was ich noch immer nicht verstehe, warum EyDu False statt True rausbekommt, für mich und Python ist 2 < 5 und egal ob nach String, bleibt 2 < 5.

Ich habe auch alle Einträge geprüft und alles ist korrekt sortiert worden.

Auf welchem Schlauch stehe ich denn?

Verfasst: Mittwoch 19. August 2009, 09:10
von cofi
Ums nochmal zu sagen: Du benutzt andere Werte als EyDu.

Code: Alles auswählen

~> python2.5
Python 2.5.4 (r254:67916, Jul 21 2009, 23:29:03)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str(2.) < str(5.)
True
>>> str(2.) < str(10.)
False
>>>
~> python2.6
Python 2.6.2 (r262:71600, Jun 23 2009, 05:47:04)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str(2.) < str(5.)
True
>>> str(2.) < str(10.)
False
>>>
~> python3.1
Python 3.1.1 (r311:74480, Aug 18 2009, 13:31:13)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str(2.) < str(10.)
False
>>> str(2.) < str(5.)

Verfasst: Mittwoch 19. August 2009, 09:18
von Yogi
cofi hat geschrieben:Ums nochmal zu sagen: Du benutzt andere Werte als EyDu.
:shock: Aflafla :shock:

Dann ist die richtige Sortierung meiner Liste nur Zufall... <schluck>

Böser böser Anfängerfehler zu übersehen, dass Strings und Zahlen für die Sortierung in ihre Ascii-Darstellung umgewandelt werden... uiuiui...

Ich sollte mir mehr Zeit nehmen......

Verfasst: Mittwoch 19. August 2009, 09:46
von EyDu
Nein, Zahlen werden bei Vergleichen nicht in ASCII-Zeichen umgewandelt. Du bist der Fehler ^^

Code: Alles auswählen

>>> "2"<"10"
False
>>> 2<10
True

Verfasst: Mittwoch 19. August 2009, 13:12
von Yogi
EyDu hat geschrieben:Nein, Zahlen werden bei Vergleichen nicht in ASCII-Zeichen umgewandelt. Du bist der Fehler ^^

Code: Alles auswählen

>>> "2"<"10"
False
>>> 2<10
True
Witzig, natürlich zu Strings konvertierte Zahlen. :roll: