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

带有用户定义cmp函数的python排序函数,python,sorted,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 firs

我想使用各种比较器函数对字典中的项目进行排序。 请参阅下面的示例代码。最后一部分是将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)
mydict={'a1':(1,6),
‘a2’:(10,2),
‘a3’:(5,3),
“a4”:(1,2),
‘a5’:(3,9),
‘a6’:(9,7)}
#按值元组的第一个元素排序:WORKS
打印排序(mydict.iteritems(),key=lambda(k,v):v[0])
#按值元组的第二个元素排序:WORKS
打印排序(mydict.iteritems(),key=lambda(k,v):v[1])
#这是我无法做到的:
def cmpRatio(x,y):
sx=浮点(x[0])/x[1]
sy=浮动(y[0])/y[1]
返回sx
如果要按值元组的总和排序(根据您的注释),可以使用:

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

如果要按比率排序(根据代码):


尽可能避免使用
cmp
功能,因为它们速度较慢。每次比较都必须重新评估它们。使用
可以使键只需计算一次

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)

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

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(…)
提供的比较器不同)

i、 e.代替

return sx < sy

请尝试使用editorI上的小
{}
框格式化您的代码,对于我要使用的两个不同比较器函数的混淆、总和和比率,我深表歉意。您的解决方案非常有效,但我的示例不仅速度慢,而且根本不起作用,我仍然想了解我做错了什么。我希望能够定义比较器函数,并将它们用作其他优化函数的参数,这就是我尝试使用cmp的根本原因。谢谢@RuxandraPalmtag:我仍然不知道你为什么想要一个
cmp
函数。您应该为密钥定义多个
lambda
操作。但是我更新了你的
cmp
函数。哦,我现在知道了:返回值,我读过但没有注册:)谢谢你的效率评论,我将尝试使用lambda键,看看它如何与我的代码一起工作!
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')
return sx < sy
return cmp(sx,sy)