Python 3中带比较函数的sorted等效方法及跨版本兼容方案
兼容Python 2.7和3.x的自定义比较排序方案
这个问题我太熟悉了!之前维护跨版本项目的时候刚好踩过这个坑——Python 3.x直接移除了sorted()函数的cmp参数,再像Python 2.7那样传双参数的比较函数,就会触发你看到的类型错误。不过确实有完美兼容两个版本的解决办法,给你推荐两种最靠谱的:
方法一:使用functools.cmp_to_key(官方推荐)
Python 2.7从2.7版本开始就内置了functools.cmp_to_key函数,Python 3.x也一直保留着它,这是最省心的兼容方案。它的作用就是把你原来那种接受两个参数、返回-1/0/1的比较函数,转换成sorted()需要的单参数key函数。
修改后的代码示例:
from functools import cmp_to_key def some_compare_func(x, y): # 这里写你的自定义比较逻辑,比如按字典的score字段排序 if x["score"] < y["score"]: return -1 # x应该排在y前面 elif x["score"] > y["score"]: return 1 # x应该排在y后面 else: return 0 # 两者顺序不变 a = sorted(some_list, key=cmp_to_key(some_compare_func))
亲测在Python 2.7和3.x环境下都能正常运行,排序结果和你原来Python 2.7的代码完全一致。
方法二:手动实现可比较的包装类(不依赖库)
如果不想导入functools模块,也可以自己写一个包装类,利用Python的比较运算符重载来实现兼容。不过这种方法代码量稍大,一般不如第一种方便,适合特殊场景下的备选方案:
class ComparableWrapper: def __init__(self, obj, compare_func): self.obj = obj self.compare_func = compare_func def __lt__(self, other): return self.compare_func(self.obj, other.obj) < 0 def some_compare_func(x, y): # 同样的自定义比较逻辑 if x < y: return -1 elif x > y: return 1 else: return 0 # 排序时先包装元素,排序后再取出原对象 a = [item.obj for item in sorted(ComparableWrapper(item, some_compare_func) for item in some_list)]
这个方法的原理是通过包装类把双参数的比较逻辑转换成单元素的<比较,从而适配sorted()的key参数逻辑,同样兼容两个版本。
总结一下,优先选方法一,官方提供的工具既简洁又可靠,完全满足你的跨版本需求。
内容的提问来源于stack exchange,提问作者MetallicPriest
相关产品推荐
相关产品推荐

