我有一个dict()调用twitter_users,它将TwitterUser对象保存为值.我希望这些对象按字段排序mentioned.但是,使用sorted()并不像我期望的那样有效.我提供了一个lambda函数,用于确定是否更频繁地提到用户a或用户b.
srt = sorted(twitter_users.values(), 
         cmp=(lambda a,b: 
              True if a.mentioned > b.mentioned else False))
for s in srt:
    print s.mentioned
不幸的是,这不起作用,列表srt没有以任何方式排序.
我怎样才能做到这一点?
Mar*_*ers 10
甲cmp函数应返回的整数,0当相等时,1或当更高a应该来后b和-1或更低,如果他们应该来以相反的顺序.
你,而不是返回False和True.因为Python布尔类型是其子类int,所以这些对象具有值0并且1在解释为整数时.你永远不会回来-1,所以你混淆了排序算法; 你告诉它的顺序,a并且b要么总是"平等",要么总是a来到之前b.但排序算法有时会要求a和b交换,在这种情况下,你给它提供了相互矛盾的信息!
请注意,你的表达相当冗长; True if a.mentioned > b.mentioned else False可以简化为a.mentioned > b.mentioned; 在>操作者已经或者产生True或False.使用简单的整数,您可以看到这不会产生预期的结果:
>>> sorted([4, 2, 5, 3, 8], cmp=lambda a, b: a > b)
[4, 2, 5, 3, 8]
实际上返回-1,0或1工作:
>>> sorted([4, 2, 5, 3, 8], cmp=lambda a, b: 1 if a > b else 0 if a == b else -1)
[2, 3, 4, 5, 8]
或者代替这种冗长的表达,只需使用内置cmp()函数 ; 对于你的情况你会像这样使用:
srt = sorted(twitter_users.values(), cmp=lambda a, b: cmp(a.mentioned, b.mentioned)) 
但是,你真的不应该使用cmp 在所有 ; 有一个更简单(更有效)的选择.只需使用该key函数,它只返回mentioned属性:
srt = sorted(twitter_users.values(), key=lambda v: v.mentioned) 
该key函数产生实际排序的值; 该函数用于产生Schwartzian变换.这种转换更有效,因为它只被称为O(n)次,而该cmp函数被称为O(n log n)次.
因为您只访问属性,所以lambda您可以使用operator.attrgetter()对象为您执行属性获取:
from operator import attrgetter
srt = sorted(twitter_users.values(), key=attrgetter('mentioned'))