用户定义的cmp函数的python排序函数

Rux*_*tag 8 python sorted

我想使用各种比较器功能在字典中订购项目.请参阅下面的示例代码.这是使用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)
Run Code Online (Sandbox Code Playgroud)

jdi*_*jdi 6

cmp尽可能避免使用功能,因为它们很慢.必须对每次比较重新评估它们.使用a key使得密钥只需要计算一次.

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

此外,您说您想要按值项的总和进行排序,但您要按差异排序.总和看起来像:

print sorted(mydict.iteritems(), key=lambda (k,v): sum(v))
Run Code Online (Sandbox Code Playgroud)

正如其他答案中所提到的,为了真正想要定义一个cmp函数,你没有返回正确的值(必须是-1,0或1).

return cmp(sx,sy)
Run Code Online (Sandbox Code Playgroud)

但是如果你只是使用lambda来获取值,你可以替换itemgetter它应该比python端函数更快:

from operator import itemgetter

print sorted(mydict.iteritems(), key=itemgetter(1), cmp=cmpRatio)
Run Code Online (Sandbox Code Playgroud)

如果您尝试存储排序操作,那么存储关键功能会更好:

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')
Run Code Online (Sandbox Code Playgroud)