2010-02-25 197 views
33

如果可能,我想使用somelist.sort()方法執行此操作。Python排序 - 對象列表

我有一個包含對象的列表,所有對象都有一個成員變量resultType,它是一個整數。我想用這個數字對列表進行排序。

我該怎麼做?

謝謝!

回答

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

這裏的另一種方式做同樣的事情,你會經常看到用:

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

你可能也想看看sorted,如果你還沒有看到它了。它不會修改原始列表 - 它會返回一個新的排序列表。

+0

你回答了我的兩個問題(attrgetter ..),並指出我有用的東西。謝謝! – Art

+0

你幫我意識到排序與排序有何不同!謝謝 – gl2748

10

當然,它不一定是拉姆達。任何函數傳入,如下面的一個,將工作

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) 

來源:Python Sorting

所以,你的情況......

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) 

上述拉姆達絕對是最緊湊這樣做的方式,但也有使用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)] 

所以你會使用itemgetter('resultType')。 (假設的GetItem定義)

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

cmp已被棄用 - 甚至不存在於Python3中。您應該使用鍵功能。 –

+1

謝謝你。我總是喜歡看非lambda方式來做事情,即使我最終會使用lambda版本(它只是感覺更性感) – NickO

+0

感謝Rizwan。比較方法很有幫助 –

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

是優於:

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

在我們在其用於成對比較的元素的比較函數通過第一種情況下在列表中。在第二種情況下,我們分配一個新的關鍵函數結果和原始值對的列表。然後我們對這個列表進行排序,然後去掉對中的關鍵值。如果你的比較功能很昂貴,這是非常有用的,但如果比較結果非常便宜,這隻會浪費內存。

也就是說,密鑰版本的擴張看起來是這樣的:

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

對於一個簡單的按鍵功能,這顯然是開銷太大,所以不是我會建議使用較輕的基於函數的排序。

請注意,cmp函數參數需要在小於,等於和大於的情況下返回-1,0,1。你可以自己寫,但你也可以使用更清晰的內置cmp函數。

+0

嘆氣,感謝@gnibbler,我不知道cmp param在Python 3中已被棄用,這很好理解。但是如果你使用python 2.x,我認爲它比關鍵版本更清晰更高效。在Python 3中,我會關注Mark Byers。 –