Seite 1 von 1
Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Dienstag 13. Juli 2010, 11:09
von rads
Hallo,
da es sich wohl um ein leichteres Problem handelt, mach ich es kurz.
Code: Alles auswählen
dicFull = {'field4':10,'field2':20,'field1':30,'field3':40}
partList = ['field4','field3']
Ich möchte partList anhand der value-Werte aus dem Dict dicFull sortieren.
Wie mache ich das in einer eleganten Version?
Schonmal vielen Dank
Grüße Stefan
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 11:34
von BlackJack
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 12:21
von rads
Super vielen Dank BlackJack.
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 13:34
von rads
Noch eine Frage,
angenommen in part_list gibt es Einträge die in dic_full nicht auftreten, dann würde er momentan eine Key-Not Found exception werfen.
Ist es möglich diese Werte "zu ignorieren" wobei ich meine das sich "einfach" am Ende unsortiert verbleiben?
Oder würde das nur über den Weg gehen, nicht im dict vorhandene Werte aus der liste entfernen und nachträglich wieder hinzufügen?
Grüße
Beispiel:
Code: Alles auswählen
dicFull = {'field4':40,'field2':20,'field1':30,'field3':10}
partList = ['field2','field4','field3','field5']
partList.sort(key=dicFull.__getitem__)
print partList
Traceback (most recent call last):
File "....py", line 13, in <module>
partList.sort(key=dicFull.__getitem__)
KeyError: 'field5'
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 13:40
von Trichter
Das könnte man vielleicht mit einem
defaultdict machen, das standardmäßig einen sehr großen Wert liefert, wenn der Eintrag nicht vorhanden ist.
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 13:52
von rads
Im moment mache ich es halt wie folgt (Testimplementierung)
Code: Alles auswählen
dicFull = {'field4':40,'field2':20,'field1':30,'field3':10}
partList = ['field2','field4','field3','field5']
tmpList = []
for part in partList:
if not dicFull.has_key(part):
partList.remove(part)
tmpList.append(part)
partList.sort(key=dicFull.__getitem__)
partList = partList + tmpList
print partList
Sicherlich nicht die idealiste Liste, aber so wie ich den sort - Befehl verstehe gibts ja keine Möglichkeit für einen skipl.
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 13:58
von EyDu
Manchmal hilft es auch ungemein nicht einfach nur Code blind zu übernehmen, sondern auch in die Dokumentation zu schauen was sort noch für mögliche Argumente hat.
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 14:20
von BlackJack
@rads: Du könntest auch einfach eine Funktion schreiben die dafür sorgt, dass für Elemente die nicht in dem Dictionary vorkommen, grundsätzlich ein höherer Wert zurückgegeben wird, als bei denen die Werte im Dictionary haben. Beispiel:
Code: Alles auswählen
dic_full = {'field4': 40, 'field2': 20, 'field1': 30, 'field3': 10}
parts = ['field2', 'field4', 'field3', 'field5']
def key_func(item):
try:
return (0, dic_full[item])
except KeyError:
return (1, None)
parts.sort(key=key_func)
print parts
Ansonsten solltest Du `list.remove()` so nicht in einer Schleife verwenden. Das wäre nicht nur ineffizient, sondern funktioniert auch nicht richtig. Wenn Du Elemente aus einer Liste entfernst, über die Du gerade iterierst, dann rutschen ja alle Folge-Elemente einen Platz nach vorne. Davon bekommt aber die Schleife nichts mit und es werden Elemente ungeprüft übersprungen.
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 14:43
von rads
@BlackJack Nochmals vielen Dank.
Ich habe es jetzt über list comprehension gemacht, fande ich dann eine zumindest optisch schön schlanke Lösung.
Code: Alles auswählen
dicFull = {'field4':40,'field2':20,'field1':30,'field3':10}
partList = ['field2','field4','field3','field5']
tmpList = [ x for x in partList if x not in dicFull.keys()]
partList = [ x for x in partList if x not in tmpList]
partList.sort( key=dicFull.__getitem__)
partList = partList + tmpList
print partList
ist ja an sich dann nicht mehr ganz so schrecklich?
Re: Sortierung
Verfasst: Dienstag 13. Juli 2010, 15:36
von BlackJack
Immer noch schrecklich. In der ersten "list comprehension" (LC) wird für jedes Element in der Liste eine Liste mit den Schlüsseln des Dictionaries erzeugt und in dem linear gesucht und in der zweiten LC werden Elemente linear in der Liste von der ersten LC gesucht. Effizient ist das nicht gerade.
Edit: So wird die `parts`-Liste nur einmal durchlaufen und auch effizient im Dictionary gesucht:
Code: Alles auswählen
dic_full = {'field4': 40, 'field2': 20, 'field1': 30, 'field3': 10}
parts = ['field2', 'field4', 'field3', 'field5']
sortable_items = list()
remaining_items = list()
for item in parts:
(sortable_items if item in dic_full else remaining_items).append(item)
sortable_items.sort(key=dic_full.__getitem__)
parts = sortable_items + remaining_items
print parts
Sortierung einer Tupe-Liste anhand einer Referenz-Liste
Verfasst: Mittwoch 14. Juli 2010, 08:18
von rads
Danke für die Anregungen BlackJack. Wurde berücksichtigt.
Anbei eine Variation und weil mich die Lösung von BlackJack interessiert hat.
Sortierung einer Tupe-Liste anhand einer Referenz-Liste wobei auch nicht alle
Werte in der Referenzliste vorhanden sein müssen
Falls es wer mal brauchen kann bzw. so wie ich nicht auf anhieb drauf kommt.
Code: Alles auswählen
orderList = ['nr4', 'nr2', 'nr3', 'nr1']
sqlMap = [('nr1', u'0'), ('nr5', u'blubb'), ('nr3', 25)]
def key_func(item):
try:
return (0, orderList.index(item[0]))
except Exception:
return (1, None)
sqlMap.sort(key=key_func)
print sqlMap
Grüße Stefan
Re: Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Mittwoch 14. Juli 2010, 12:31
von mkesper
ist eine schreckliche Idee!
Re: Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Mittwoch 14. Juli 2010, 12:38
von Barabbas
Ich habe gehört, man spricht in diesem Fall auch von "Pokeman-Exceptions" ("Catch 'em all!")

Re: Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Donnerstag 15. Juli 2010, 12:25
von cofi
mkesper hat geschrieben: ist eine schreckliche Idee!
Na immerhin besser als ein blankes `except`.
@rads: Warum die Faulheit? `ValueError` ist nicht sonderlich laenger.
Re: Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Donnerstag 15. Juli 2010, 13:42
von rads
@cofi
naja ich bin javaverwöhnt in kombination von eclipse, da ist die Refactoringfunktionaliät, naja sagen wir mal ausgeprägter, als bei Pydev.
An sich liegt es daran, das er bei der automatischen generierung des try:except: Blockes Exception schreibt,und nicht die
eigentlich möglichen auftretenden Exceptions. Ka wo ich das einstellen kann, aber ja es ist wohl schlichte Faulheit.
Re: Sortierung von Listen (Tupel-Listen) anhand einer Liste
Verfasst: Donnerstag 15. Juli 2010, 15:40
von Leonidas
rads hat geschrieben:Ka wo ich das einstellen kann, aber ja es ist wohl schlichte Faulheit.
Nein, das lässt sich nicht statisch ermitteln. Jedenfalls ist das
so keine gute Einstellung.