python - 在排序期间使用多个字段进行键评估的pythonic方法是什么?
问题描述
Python3 去掉了排序时用来比较的cmp
参数,取而代之的是key
.
引入该cmp_to_key
函数是为了“主要用作从 Python 2 转换的程序的转换工具”。
我不清楚如何cmp
在 python3 中使用key
. 例如,如果我想按长度对字符串进行排序,并按字典顺序使用决胜局,我会这样写:
def compare(word1, word2):
if len(word1) > len(word2):
return 1
if len(word2) > len(word1):
return -1
if word1 < word2:
return 1
if word2 < word1:
return -1
return 0
myStrings.sort(key=functools.cmp_to_key(compare), reverse=True)
如何以python3-native方式进行对象之间的比较,意思是没有cmp_to_key
?
我能想到的一件事是返回一个更复杂的密钥,例如:
# This would return something like 5.12 for "hello" and 5.20 for "world"
def myKey(word):
return len(word) + myLexicographicalValueFunction(word)/100
myStrings.sort(key=myKey, reverse=True)
但是,当您添加更多变量进行比较时,这似乎并不能很好地扩展。在python3中排序期间使用多个字段进行键评估的pythonic方法是什么?
解决方案
对于该特定比较,您可以使用元组作为键:
myStings.sort(key=lambda s:(-len(s),s),reverse=True)
对于对象类,您可能需要实现一个比较运算符(例如def __lt__(self,other):
方法)来让排序知道如何在本地比较它们。
如果您无法修改对象类或者您的比较非常复杂,您可以创建一个包装器对象,该对象__lt__()
使用您提供的 lambda 实现该方法:
class ObjectComp:
def __init__(self,instance,cmp):
self.instance = instance
self.cmp = cmp
def __lt__(self,other):
return self.cmp(self.instance,other.instance)
def cmpsort(objects,cmp):
return [obj.instance for obj in sorted(ObjectComp(o,cmp) for o in objects)]
s = cmpsort([1,11,21,12,13],cmp=lambda a,b:a%10>b%10)
print(s)
[13, 12, 1, 11, 21]
推荐阅读
- python - 如何为 celery 任务日志指定文件路径?
- reactjs - 反应笑话快照测试 - 更改目录结构
- vb.net - 如果语句为真,则 End If 不会立即继续
- python - 在 Scrapy 中使用分页访问多个页面
- pandas - Should I use classes for pandas.DataFrame?
- python - 在同一个 .py 文件上与另一个人进行实时协作?
- node.js - 如何使用 mongoose 和 Node.js 请求新创建的模型?
- javascript - 如何在新行上粘贴复制的链接?
- prolog - 将列表列表转换为 Prolog 中的列表
- laravel - 当我在 Laravel 中通过参数更改值时出现请求问题