2010-02-25 2 views
33

Ich würde gerne die somelist.sort() -Methode verwenden, um dies zu tun, wenn möglich.Python-Sortierung - Eine Liste von Objekten

Ich habe eine Liste mit Objekten, alle Objekte haben eine Membervariable resultType, die eine ganze Zahl ist. Ich möchte die Liste mit dieser Nummer sortieren.

Wie mache ich das?

Danke!

Antwort

67
somelist.sort(key = lambda x: x.resultType) 

Hier ist ein weiterer Weg, um das Gleiche zu tun, dass Sie oft gebraucht:

import operator 
s.sort(key = operator.attrgetter('resultType')) 

Sie könnten auch bei sorted aussehen wollen, wenn Sie es nicht schon gesehen. Es ändert nicht die ursprüngliche Liste - es gibt eine neue sortierte Liste zurück.

+0

Sie beantwortet zwei meiner Fragen (attrgetter ..) und zeigte mir etwas Nützliches. Vielen Dank! – Art

+0

Sie haben mir geholfen zu erkennen, wie sich Sortierung von Sortierung unterscheidet! Danke – gl2748

10

Natürlich muss es kein Lambda sein. Jede Funktion übergeben, wie die folgenden ein, arbeiten

def numeric_compare(x, y): 
    if x > y: 
     return 1 
    elif x == y: 
     return 0 
    else: #x < y 
     return -1 

a = [5, 2, 3, 1, 4] 
a.sort(numeric_compare) 

Quelle: Python Sorting

Also, in Ihrem Fall ...

def object_compare(x, y): 
    if x.resultType > y.resultType: 
     return 1 
    elif x.resultType == y.resultType: 
     return 0 
    else: #x.resultType < y.resultType 
     return -1 

a.sort(object_compare) 

Die zuvor genannte Lambda ist auf jeden Fall das kompakteste Art und Weise, es zu tun, aber es gibt auch operator.itemgetter.

import operator 
#L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] 
map(operator.itemgetter(0), L) 
#['c', 'd', 'a', 'b'] 
map(operator.itemgetter(1), L) 
#[2, 1, 4, 3] 
sorted(L, key=operator.itemgetter(1)) 
#[('d', 1), ('c', 2), ('b', 3), ('a', 4)] 

Sie würden also itemgetter ('resultType') verwenden. (. Unter der Annahme GetItem definiert)

sorted(L, key=operator.itemgetter('resultType')) 
+1

cmp ist veraltet - existiert nicht einmal in Python3. Sie sollten stattdessen eine Schlüsselfunktion verwenden. –

+1

Vielen Dank dafür.Ich mag es immer, Nicht-Lambda-Arten zu sehen, Dinge zu tun, selbst wenn ich letztendlich die Lambda-Version verwenden werde (es fühlt sich einfach sexier an) – NickO

+0

Danke Rizwan. die Vergleichs-Methode war hilfreich –

1
somelist.sort(cmp = lambda x, y: cmp(x.resultType, y.resultType)) 

besser ist als:

somelist.sort(key = lambda x: x.resultType) 

Im ersten Fall wir in einer Vergleichsfunktion übergeben, das verwendet wird, um paarweise die Elemente vergleichen, In der Liste. Im zweiten Fall ordnen wir eine neue Liste von Paaren des Ergebnisses der Schlüsselfunktion und des ursprünglichen Wertes zu. Dann sortieren wir diese Liste und entfernen dann die Schlüsselwerte von den Paaren. Dies ist sehr nützlich, wenn Ihre Vergleichsfunktion teuer ist, aber nur eine Verschwendung von Speicher, wenn der Vergleich wirklich billig ist.

, dass die Erweiterung der Schlüsselversion ist, sieht ungefähr so ​​aus:

l = [y for x,y in sorted(zip([key(i) for i in l], l))] 

Für eine einfache Tastenfunktion, das ist eindeutig zu viel Aufwand, so stattdessen würde ich vorschlagen, die leichtere Funktion basierend Art verwenden.

Beachten Sie, dass der Parameterparameter cmp -1, 0, 1 in den Fällen kleiner, gleich und größer als zurückgeben muss. Sie könnten das selbst schreiben, aber Sie können auch die eingebaute cmp-Funktion verwenden, die klarer ist.

+0

Seufz, danke @gnibbler, ich wusste nicht, dass der CMP Param in Python 3 veraltet war, das ist gut zu wissen. Aber wenn Sie in Python 2.x sind, denke ich, dass es klarer und effizienter als die Schlüsselversion ist. In Python 3 würde ich Mark Byers folgen. –