简体   繁体   English

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

[英]python sorted function with user defined cmp functions

I want to order the items in a dictionary using various comparator functions. 我想使用各种比较器功能在字典中订购项目。 Please see my example code below. 请参阅下面的示例代码。 It is the last part using cmpRatio function with sorted() that does not work. 这是使用cmpRatio函数和sorted()的最后一部分,它不起作用。 I am not sure what I am doing wrong. 我不确定我做错了什么。 Thanks in advance for any idea! 提前感谢任何想法!

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)

Avoid cmp functions where possible because they are slow. 尽可能避免使用cmp函数,因为它们很慢。 They have to be re-evaluated for each comparison. 必须对每次比较重新评估它们。 Using a key makes it so the key only needs to be computed once. 使用key使得密钥只需要计算一次。

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

Also, you say you want to sort by the sum of the value items, yet you are sorting by the difference. 此外,您说您想要按值项的总和进行排序,但您要按差异排序。 Sum would look like: 总和看起来像:

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

As mentioned in other answers, for the purpose of really wanting to define a cmp function, you are not returning the proper value (must be -1,0, or 1). 正如其他答案中所提到的,为了真正想要定义一个cmp函数,你没有返回正确的值(必须是-1,0或1)。

return cmp(sx,sy)

But also if you are just using a lambda to get the value, you can replace that with itemgetter which should be faster than a python-side function: 但是如果你只是使用lambda来获取值,你可以用itemgetter替换它,它应该比python-side函数更快:

from operator import itemgetter

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

If you are trying to store up sort operations, it would be much better to store the key functions: 如果您尝试存储排序操作,那么存储关键功能会更好:

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')

you comparison function should return a (negative / zero / positive) value when the first argument is (less than / equal to / greater than) the second value (unlike a comparator given to std::sort(...) in C++). 当第一个参数是(小于/等于/大于)第二个值时,比较函数应该返回一个(负/零/正)值(与C ++中给定为std::sort(...)的比较器不同) 。

ie instead of 即代替

return sx < sy

do

return cmp(sx,sy)

If you want to sort by the sum of the value tuple (according to your comment), you could use : 如果你想按值元组的总和排序(根据你的评论),你可以使用:

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

If you want to sort by the ratio (according to your code): 如果要按比例排序(根据您的代码):

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