2012-11-21 117 views
8

我想使用各种比较函数来排序字典中的项目。 请参阅下面的示例代码。这是使用cmpRatio函数和sorted()不起作用的最后一部分。我不确定我做错了什么。预先感谢您的任何想法!使用用户定义的cmp函数的python排序函数

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) 
+0

请尽量使用小'{}'框中编辑 –

回答

6

避免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这应该是比蟒蛇端函数更快:

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

我的困惑,总和比在两个道歉格式化你的代码我想要使​​用的各种比较器功能。你的解决方案工作得很好,但我的例子不仅速度慢,而且还不起作用,而且我还想了解我做错了什么。我想能够定义比较函数并将它们用作某些其他优化函数的参数,这是我尝试使用cmp的基本原因。谢谢! –

+0

@RuxandraPalmtag:我仍然不知道你为什么要'cmp'功能。您应该为该键定义多个'lambda'操作。但我更新了你的'cmp'功能。 – jdi

+0

哦,我现在明白了:返回值,我读了它,但没有注册:)谢谢你的效率评论,我会尝试使用lambda键,看看它如何与我的代码工作! –

2

如果您想通过值元组的总和进行排序(根据您的评论),你可以使用:

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

如果你想比排序(根据你的代码):

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

你比较函数应该返回(负/零/负)值,当第一argum ent是(小于/等于/大于)第二个值(不同于在C++中给出的std::sort(...)的比较器)。的

即代替

return sx < sy 

return cmp(sx,sy)