2011-03-06 102 views
34

我知道有幾個像這樣命名的問題,但我似乎無法得到他們的答案。在Python中使用自定義比較函數對列表進行排序列表

我有一個清單列表,50次5個元素。現在我想通過對每個元素應用自定義比較函數來對這個列表進行排序。該函數計算元素排序的列表的適應度。我創建了兩個功能,比較和健身:

def compare(item1, item2): 
    return (fitness(item1) < fitness(item2)) 

def fitness(item): 
    return item[0]+item[1]+item[2]+item[3]+item[4] 

然後我試圖打電話給他們:

sorted(mylist, cmp=compare) 

sorted(mylist, key=fitness) 

sorted(mylist, cmp=compare, key=fitness) 

sorted(mylist, cmp=lambda x,y: compare(x,y)) 

另外我試圖list.sort()具有相同的參數。但在任何情況下,這些函數都不會獲得一個列表作爲參數,而是一個None。我不知道這是爲什麼,大部分來自C++,這與我的回調函數的任何想法都是矛盾的。我如何使用自定義函數對這個列表進行排序?

編輯 我發現我的錯誤。在創建原始列表的鏈中,一個函數沒有返回任何內容,但是使用了返回值。對不起,煩擾

+2

顯示的代碼,你還指望什麼,你會得到什麼。 – delnan 2011-03-06 20:15:33

+2

請注意,您的'compare'函數是不正確的,因爲它只返回True或False,並且不區分'item1'和'item2'是否相等,'item1'大於'item2'。寫'compare'的正確方法是返回'cmp(fitness(item1),fitness(item2))'。但使用'key'更好。 – jchl 2011-03-07 10:04:40

回答

23
>>> l = [list(range(i, i+4)) for i in range(10,1,-1)] 
>>> l 
[[10, 11, 12, 13], [9, 10, 11, 12], [8, 9, 10, 11], [7, 8, 9, 10], [6, 7, 8, 9], [5, 6, 7, 8], [4, 5, 6, 7], [3, 4, 5, 6], [2, 3, 4, 5]] 
>>> sorted(l, key=sum) 
[[2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9, 10], [8, 9, 10, 11], [9, 10, 11, 12], [10, 11, 12, 13]] 

上述工作。你在做一些不同的事情嗎?

請注意,您的關鍵功能只是sum;沒有必要明確寫出它。

+1

你是絕對正確的,其他一些代碼導致了錯誤,謝謝。再次感謝你,至少現在我有一個使用函數而不是lambda表達式作爲鍵值的示例。我以前找到解決方案時找不到一個。 – DaClown 2011-03-07 08:49:35

51

此外,您的比較功能不正確。它需要返回-1,0或1,而不是布爾值。正確的比較功能是:

def compare(item1, item2): 
    if fitness(item1) < fitness(item2): 
     return -1 
    elif fitness(item1) > fitness(item2): 
     return 1 
    else: 
     return 0 
+21

或者只是,'返回健身(item1) - 健身(item2)'。比較函數不必返回-1或1,而只需返回一個負數或正數(或零)。參考:http://docs.python.org/2/library/stdtypes.html#mutable-sequence-types – LarsH 2013-01-18 21:53:36

+6

'sorted(myList,key = lambda x:-fitness(x))' – 2015-05-21 13:45:16

+3

或'sorted(myList, key = fitness,reverse = True)' – orange 2015-12-26 00:42:15

3

你需要稍微修改您的compare功能和使用functools.cmp_to_key將它傳遞給sorted。示例代碼:

import functools 

lst = [list(range(i, i+5)) for i in range(5, 1, -1)] 

def fitness(item): 
    return item[0]+item[1]+item[2]+item[3]+item[4] 
def compare(item1, item2): 
    return fitness(item1) - fitness(item2) 

sorted(lst, key=functools.cmp_to_key(compare)) 

輸出:

[[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9]] 

作品:)

相關問題