来自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
举个例子:
>>> 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__ and not __cmp__
再说一遍,为什么要这样推荐?我能不能不定义__cmp__
让生活更简单?
cmp
被删除是因为.sort()
和sorted()
的key
属性在大多数情况下是优越的。这是C语言的一个延迟,而且启动起来很混乱。在富比较运算符(__lt__
,__gt__
等)之后,必须实现单独的__cmp__
方法。您始终可以使用^{} 来调整现有的
cmp
函数。当然,由于整数已经是可排序的,您的特定示例可以在不使用
key
函数的情况下实现;只需添加reverse=True
。对于自定义类,使用^{} decorator 将
__eq__
和一个比较运算符方法(例如__lt__
,或__gt__
,等等)展开为完整的排序实现。对于两个对象
a
和b
,__cmp__
要求其中一个a < b
,a == b
,和a > b
是真的。但情况可能并非如此:考虑集合,在集合中,没有一个是真的,例如{1, 2, 3}
与{4, 5, 6}
。于是
__lt__
和朋友们被介绍了。但这让Python有了两个独立的排序机制,这有点荒谬,所以在Python 3中去掉了不太灵活的机制。实际上,您不必实现所有六种比较方法。您可以使用^{} decorator ,并且只实现
__lt__
和__eq__
。编辑:还要注意,在排序的情况下,
key
函数可能比cmp
更有效:在您给出的示例中,Python可能需要调用Python比较函数O(nã)次。但是一个key
函数只需要调用O(n)次,如果返回值是一个内置类型(通常是这样),那么O(n)对比较将通过C相关问题 更多 >
编程相关推荐