簡體   English   中英

用戶定義的cmp函數的python排序函數

[英]python sorted function with user defined cmp functions

我想使用各種比較器功能在字典中訂購項目。 請參閱下面的示例代碼。 這是使用cmpRatio函數和sorted()的最后一部分,它不起作用。 我不確定我做錯了什么。 提前感謝任何想法!

mydict = { 'a1': (1,6),
          'a2': (10,2),
          'a3': (5,3),
          'a4': (1,2),
          'a5': (3,9),
          'a6': (9,7) }

# sort by first element of the value tuple: WORKS
print sorted(mydict.iteritems(), key=lambda (k,v): v[0])

# sort by second element of the value tuple: WORKS
print sorted(mydict.iteritems(), key=lambda (k,v): v[1])

# THIS is what I can't get working:
def cmpRatio(x,y):
   sx = float(x[0])/x[1]
   sy = float(y[0])/y[1]
   return sx < sy

# sort by sum of the elements in the value tuple: DOES NOT WORK
print sorted(mydict.iteritems(), key=lambda (k,v): v, cmp=cmpRatio)

盡可能避免使用cmp函數,因為它們很慢。 必須對每次比較重新評估它們。 使用key使得密鑰只需要計算一次。

print sorted(mydict.iteritems(), key=lambda (k,v): float(v[0])/v[1])

此外,您說您想要按值項的總和進行排序,但您要按差異排序。 總和看起來像:

print sorted(mydict.iteritems(), key=lambda (k,v): sum(v))

正如其他答案中所提到的,為了真正想要定義一個cmp函數,你沒有返回正確的值(必須是-1,0或1)。

return cmp(sx,sy)

但是如果你只是使用lambda來獲取值,你可以用itemgetter替換它,它應該比python-side函數更快:

from operator import itemgetter

print sorted(mydict.iteritems(), key=itemgetter(1), cmp=cmpRatio)

如果您嘗試存儲排序操作,那么存儲關鍵功能會更好:

key_ops = {
    'sum': lambda (k,v): sum(v),
    'ratio': lambda (k,v): float(v[0])/v[1]),
}

def print_op(aDict, opName):
    print sorted(aDict.iteritems(), key=key_ops[opName])

... # some place later in code
print_op(mydict, 'sum')

當第一個參數是(小於/等於/大於)第二個值時,比較函數應該返回一個(負/零/正)值(與C ++中給定為std::sort(...)的比較器不同) 。

即代替

return sx < sy

return cmp(sx,sy)

如果你想按值元組的總和排序(根據你的評論),你可以使用:

print sorted(mydict.iteritems(), key=lambda v: sum(v[1]))

如果要按比例排序(根據您的代碼):

print sorted(mydict.iteritems(), key=lambda v: float(v[1][0])/v[1][1])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM