2010-07-09 12 views
37

Wie kann ich durch eine beliebige Funktion beschrieben eine Liste nach einem Schlüssel sortiert werden? Zum Beispiel, wenn ich habe:Sortierung nach beliebigem Lambda

Ich würde "mylist" durch das zweite Element jedes Mitglieds, z.

sort(mylist, key=lambda x: x[1]) 

Wie kann ich das tun?

+0

Was war das Problem, als Sie den von Ihnen bereitgestellten Code ausprobierten? – tzot

Antwort

37

Sie es im Grunde schon haben:

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> mylist.sort(key=lambda x: x[1]) 
>>> print mylist 

gibt:

[['bar', 0, 'b'], ['quux', 1, 'a']] 

Das wird meine Liste an Ort und Stelle sortieren.

[dieses Para editiert dank @ Daniels Korrektur.] sorted gibt eine neue Liste zurück, die sortiert ist, anstatt die Eingabe tatsächlich zu ändern, wie in http://wiki.python.org/moin/HowTo/Sorting/ beschrieben.

+0

Gut zu wissen, die Auszeichnung, danke. – user248237dfsf

4

Die Antwort ist "sortiert", dh

sorted(mylist, key=lambda x: x[1]) 
+0

Ich hatte die Parameter rückwärts. Scheint inkonsistent, dass z.B. map/filter/reduce nimmt den ersten Lambda-Parameter und listet den zweiten Parameter auf, sortiert aber den umgekehrten. – javadba

7

Sie haben zwei Möglichkeiten zu nutzen, ganz in der Nähe, was Sie beschrieben, tatsächlich:

mylist.sort(key=lambda x: x[1]) # In place sort 
new_list = sorted(mylist, key=lambda x: x[1]) 
9

Dies ist ein solches gemeinsames Bedürfnis, die es unterstützen, hat der Standard-Bibliothek, in der Form von operator.itemgetter hinzugefügt:

from operator import itemgetter 
mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
mylist.sort(key=itemgetter(1)) # or sorted(mylist, key=...) 
4

Sortieren und itemgetter ist der schnellste.

>>> import operator 
>>> import timeit 

>>> mylist = [["quux", 1, "a"], ["bar", 0, "b"]] 
>>> t1 = timeit.Timer(lambda: mylist.sort(key=lambda x: x[1])) 
>>> t1.timeit() 
1.6330803055632404 

>>> t2 = timeit.Timer(lambda: mylist.sort(key=operator.itemgetter(1))) 
>>> t2.timeit() 
1.3985503043467773 

>>> t3 = timeit.Timer(lambda: sorted(mylist, key=operator.itemgetter(1))) 
>>> t3.timeit() 
2.6329514733833292 

>>> t4 = timeit.Timer(lambda: sorted(mylist, key=lambda x: x[1])) 
>>> t4.timeit() 
2.9197154810598533 
Verwandte Themen