bra*_*orm 36 python sorting object cmp
来自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]
Run Code Online (Sandbox Code Playgroud)
现在考虑这个版本(推荐并与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]
Run Code Online (Sandbox Code Playgroud)
后者非常冗长,前者只用一行就达到了同样的目的.另一方面,我正在编写我想要编写__cmp__方法的自定义类.从我在网上的小阅读,建议再写__lt__,__gt__,__eq__,__le__,__ge__,__ne__ and not __cmp__
一次,为什么这个推荐?我不能只是定义__cmp__让生活更简单吗?
Eev*_*vee 25
对于两个物体a和b,__cmp__要求之一 a < b,a == b和a > b是真实的.但是,这可能并非如此:考虑套,它是非常普遍,这些都不是真实的,例如{1, 2, 3}VS {4, 5, 6}.
所以__lt__和朋友们介绍了.但是这给Python留下了两个独立的排序机制,这有点荒谬,因此在Python 3中删除的灵活性较低.
您实际上不必实现所有六种比较方法.你可以使用@total_ordering装饰器,只实现__lt__和__eq__.
编辑:还要注意,在排序的情况下,key函数可以比cmp以下更有效:在您给出的示例中,Python可能必须调用您的Python比较函数O(n²)次.但是key函数只需要被称为O(n)次,如果返回值是内置类型(通常是这样),则O(n²)成对比较通过C.
Mar*_*ers 14
cmp被删除,因为在大多数情况下key属性为.sort()和sorted()优越.它比C更能阻止C,并且引起了混乱.不必实现一个单独的__cmp__方法旁边的富比较运算符(__lt__,__gt__,等)是令人迷惑和无助.
您始终可以使用它functools.cmp_to_key()来调整现有cmp功能.
你的具体的例子可能已经实现没有一个key功能,当然,作为整数已订购; 只需添加reverse=True.
对于自定义类,使用@functools.total_ordering装饰器将一个__eq__和一个比较运算符方法(例如__lt__,或__gt__等)扩展为完整的排序实现.