为什么从Python3.0中的sort/sorted中删除了cmp参数? [英] Why is the cmp parameter removed from sort/sorted in Python3.0?
问题描述
来自 python Wiki :
In Py3.0, the cmp parameter was removed entirely (as part of a larger effort to simplify and unify the language, eliminating the conflict between rich comparisons and the __cmp__ methods).
我不明白为什么在py3.0中删除了cmp的原因
I do not understand the reasoning why cmp is removed in py3.0
考虑以下示例:
>>> def numeric_compare(x, y):
return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]
,现在考虑使用此版本(推荐并与3.0兼容):
and now consider this version (recommended and compatible with 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__ and not __cmp__
同样,为什么要提出这个建议?我不仅可以定义__cmp__
来简化生活吗?
The latter is very verbose and the same purpose is achieved in the former with just one line. On another note, I am writing my custom class for which I want to write the __cmp__
method. from my little reading across web, it is recommended to write __lt__,__gt__,__eq__,__le__,__ge__,__ne__ and not __cmp__
Again, why this recommendation? can I not just define __cmp__
making life simpler?
推荐答案
对于两个对象a
和b
,__cmp__
要求 a < b
,a == b
,并且a > b
为true.但这可能并非如此:请考虑集合,其中都不是真的是很常见的,例如{1, 2, 3}
与{4, 5, 6}
.
For two objects a
and b
, __cmp__
requires that one of a < b
, a == b
, and a > b
is true. But that might not be the case: consider sets, where it's very common that none of those are true, e.g. {1, 2, 3}
vs {4, 5, 6}
.
因此介绍了__lt__
和朋友.但这给Python留下了两种单独的排序机制,这有点荒谬,因此在Python 3中删除了较不灵活的排序机制.
So __lt__
and friends were introduced. But that left Python with two separate ordering mechanisms, which is kind of ridiculous, so the less flexible one was removed in Python 3.
您实际上不必实现所有六个比较方法.您可以使用 @total_ordering
装饰器,并且仅实现__lt__
和__eq__
You don't actually have to implement all six comparison methods. You can use the @total_ordering
decorator and only implement __lt__
and __eq__
.
edit:还请注意,在排序的情况下,key
函数可能比cmp
更有效:在您给出的示例中,Python可能必须调用Python比较函数O(n²)次.但是key
函数仅需要调用O(n)次,并且如果返回值是内置类型(通常是这样),则O(n²)成对比较将通过C.
edit: Also note that, in the case of sorting, key
functions can be more efficient than cmp
: in the example you gave, Python may have to call your Python comparison function O(n²) times. But a key
function only needs to be called O(n) times, and if the return value is then a builtin type (as it very often is), the O(n²) pairwise comparisons go through C.
这篇关于为什么从Python3.0中的sort/sorted中删除了cmp参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!