Python:使用自定义比较器排序一系列字典

前端之家收集整理的这篇文章主要介绍了Python:使用自定义比较器排序一系列字典前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下 Python数组的字典:
myarr = [ { 'name': 'Richard','rank': 1 },{ 'name': 'Reuben','rank': 4 },{ 'name': 'Reece','rank': 0 },{ 'name': 'Rohan','rank': 3 },{ 'name': 'Ralph','rank': 2 },{ 'name': 'Raphael',{ 'name': 'Robin','rank': 0 } ]

我想按等级排序,排序如下:1-2-3-4-0-0-0.

如果我尝试:

sorted_master_list = sorted(myarr,key=itemgetter('rank'))

那么列表按照0-0-0-1-2-3-4的顺序进行排序.

如何定义自定义比较器函数将零推到列表的底部?我想知道是否可以使用像methodcaller这样的东西.

解决方法

选项1:
key=lambda d:(d['rank']==0,d['rank'])

选项二:

key=lambda d:d['rank'] if d['rank']!=0 else float('inf')

演示:

“I’d like to sort it by the rank values,ordering as follows: 1-2-3-4-0-0-0.” –original poster

>>> sorted([0,1,2,3,4],key=lambda x:(x==0,x))
[1,4,0]

>>> sorted([0,key=lambda x:x if x!=0 else float('inf'))
[1,0]

补充评论

“Please could you explain to me (a Python novice) what it’s doing? I can see that it’s a lambda,which I know is an anonymous function: what’s the bit in brackets?” – OP comment

索引/切片符号:

itemgetter(‘rank’)与lambda x相同:x [‘rank’]与函数相同:

def getRank(myDict):
    return myDict['rank']

[…]被称为索引/切片符号,请参见Explain Python’s slice notation – 另请注意,someArray [n]是许多编程语言中的常用符号,用于索引,但可能不支持[start:end]或[start :端:步骤].

key = vs cmp = vs丰富的比较:

至于发生了什么,有两种常用的方法来指定排序算法的工作原理:一种是关键功能,另一种是使用一个cmp函数(现在在python中已经不再使用,但是更多功能).而cmp函数允许您任意指定两个元素应如何比较(输入:a,b;输出:a 代码),关键的功能对你来说更为自然.="" (请参阅“对象丰富的比较”,了解如何以优雅但可能过多的方式隐式定义cmp=")" 实现您的主要功能:="" 不幸的是,0是整数的元素,因此具有自然排序:0通常是<="" 1,3="" ...因此,如果我们想强加一个额外的规则,我们需要在“更高级别”排序列表.我们通过将键作为元组来实现:元组首先由其第一个元素排序,然后由其第二个元素排序.真的将永远在false之后被命令,所以所有trues将在falses之后被命令;它们将按照正常排序:(true,1)<(true,2)<(true,3)<="" ...,(false,1)<(false,2)="" (假,*)≤(真,*).替代方案(选项2)仅仅是将0级字典赋值为无穷大,因为这被保证高于任何可能的等级.="" 更一般的替代="" –="" 对象丰富的比较:="" 更通用的解决方案是创建一个表示记录的类,然后实现__lt__,__gt__,__eq__,__ne__,__ge__和所有其他 rich comparison operators,或者只是实现其中一个和__eq__并使用 @functools.total_ordering decorator.这将导致该类的对象在使用比较运算符时使用自定义逻辑(例如x = Record(name =’Joe’,rank = 12)y = Record(…)x< y);由于排序(...)函数使用<和其他比较运算符在默认情况下进行比较排序,这将使排序时自动执行行为,在其他情况下,您使用<和其他比较运算符.这可能是也可能不会过多,这取决于你的用例. 清除替代方案 – 不要超载0与语义: 但是我应该指出,将0s放在1,4等之后有点人为.这是否合理取决于rank = 0是否真的意味着rank = 0;如果rank = 0真的比rank = 1低(这反过来比rank = 2更“低”).如果这是真的,那么你的方法是完美的.如果不是这样,那么你可以考虑省略’rank’:…条目而不是设置’rank’:0.那么你可以用Lev Levitsky的答案,使用d中的“rank”,或者通过: 方案1具有不同的方案:

key=lambda d: (not 'rank' in d,d['rank'])

方案2具有不同的方案:

key=lambda d: d.get('rank',float('inf'))

sidenote:依​​靠python中的无穷大的存在几乎是一个黑客的边界,提出任何提到的解决方案(元组,对象比较),Lev的filter-then-concatenate solution,甚至可能是稍微复杂的cmp solution(由威尔逊打字),更多可泛化到其他语言.

原文链接:https://www.f2er.com/python/186603.html

猜你在找的Python相关文章