Sortieren vom PSP-IDs

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
\^/ili
User
Beiträge: 9
Registriert: Samstag 8. Juni 2013, 19:57

Hallo,

ich soll ene Liste mit Strings, welche durch Punkte getrennte Zahlen (z.B. "1.2.3") beinhalten sortieren.
Ein "normaler" sort würde "10.1" klarerweise nach "1.2" und vor "2.x" reihen (so wie im Beispiel in der Liste).
Mögen aus unerfindlichen gründen die user nicht so gerne :)

Um das Problem zu lösen habe ich fogendes programmiert.
HINT: das zweite Element bruauche ich zur weiteren Verarbeitung.

Code: Alles auswählen

psp = [
   ['1',1],
   ['1.1',7],
   ['1.1.1',9],
   ['10',5],
   ['10.1',6],
   ['2',2],
   ['3',3],
   ['3.1',8],
   ['3.1.1.1',4],
   ]

for x in sorted([''.join(['{0:>5s}.'.format(x) for x in i[0].split('.')]) for i in psp]):
   x = x.replace(' ','').strip('.')
   q = next((i for i in psp if i[0] == x), None)
   print q[0],':',q[1]

Das macht zwar alles richtig aber ist kommt mir nicht sehr elegant vor - genaugemommen ziemlich "grauslich".
Ich könnte das alles in "zwischen-Listen" auflösen, macht es aber auch nicht wirklich besser.

Ich kann auch nicht die maximale 'tiefe' vorhersagen es könnte auch "1.1.1.1.1.1.1.1" vorkommen.

Hat jemamd das Problem schon eleganter gelöst?

Lg
\^/ili
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

\^/ili hat geschrieben:Hat jemamd das Problem schon eleganter gelöst?
Die Methode sort der Liste hat einen Parameter key für die Angabe des Sortierschlüssels. Dort kann man auch kurz ein Lambda angeben. Was wir eigentlich nur brauchen ist das erste Element jedes Listeneintrags. Das zerlegen wir mit Hilfe von split an den Punkten in Einzelteile und konvertieren die Ziffern in echte Zahlen.

Code: Alles auswählen

psp.sort(key=lambda x: map(int, x[0].split('.')))
Sollte dich die Zeile verwirren, dann schau dir mal folgenden Code an in dem ich grob die Idee dahinter zusammengefasst habe.

Code: Alles auswählen

# zerlegen
for element in psp:
    parts = element[0].split('.')
    parts = map(int, parts)
    element[0] = parts
psp.sort()
print(psp)

# wieder zusammenbauen (die Variante mit key braucht das nicht)
for element in psp:
    parts = map(str, element[0])
    element[0] = '.'.join(parts)
print(psp)
Zuletzt geändert von /me am Mittwoch 10. Juli 2013, 09:32, insgesamt 1-mal geändert.
BlackJack

Vielleicht noch als Anmerkung: Im Original ist das zuordnen von Sortierschlüssel zu Element in der ursprünglichen Liste extrem gruselig was die Laufzeit angeht. Die wächst quadratisch mit der Anzahl der Elemente.
\^/ili
User
Beiträge: 9
Registriert: Samstag 8. Juni 2013, 19:57

Hallo,

Code: Alles auswählen

psp.sort(key=lambda x: map(int, x[0].split('.')))
BESTEN Dank genau nach dem habe ich gesucht!

Manchmal sieht man halt den Wald vor lauter Bäumen nicht.
Und wiedermal ist der Tag gerette weil ich hab' was gelernt.

lg
\^/ili
Antworten