来自 python wiki :
在 Py3.0 中,cmp 参数被完全删除(作为简化和统一语言的更大努力的一部分,消除了丰富的比较和 __cmp__ 方法之间的冲突)。
不明白py3.0中去掉cmp的原因
考虑这个例子:
>>> def numeric_compare(x, y):
return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]
现在考虑这个版本(推荐并兼容 3.0):
def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
return K
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]
后者非常冗长,而前者仅用一行就达到了相同的目的。另一方面,我正在编写我想为其编写 __cmp__
方法的自定义类。根据我在网上的一点阅读,建议写 __lt__,__gt__,__eq__,__le__,__ge__,__ne__ 而不是 __cmp__
再次,为什么这个建议?我不能只定义 __cmp__
让生活更简单吗?
最佳答案
对于两个对象 a
和 b
, __cmp__
要求 其中一个 a < b
, a == b
, 和 a > b
是真的。但情况可能并非如此:考虑集合,其中 没有一个 是非常常见的,例如{1, 2, 3}
与 {4, 5, 6}
.
所以 __lt__
和 friend 介绍了。但这给 Python 留下了两个独立的排序机制,这有点荒谬,所以在 Python 3 中删除了不太灵活的排序机制。
您实际上不必实现所有六种比较方法。您可以使用 @total_ordering
decorator并且只执行 __lt__
和 __eq__
.
编辑:还要注意,在排序的情况下,key
函数可能比 cmp
更有效:在您给出的示例中,Python 可能必须调用您的 Python 比较函数 O(n²) 次。但是一个key
函数只需要调用 O(n) 次,如果返回值是内置类型(通常是这样),则 O(n²) 成对比较通过 C 进行。
关于python - 为什么在 Python3.0 中将 cmp 参数从 sort/sorted 中删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20202418/