为什么在 Python3.0 中从 sort/sorted 中删除了 cmp 参数? [英] Why is the cmp parameter removed from sort/sorted in Python3.0?

查看:48
本文介绍了为什么在 Python3.0 中从 sort/sorted 中删除了 cmp 参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 python 维基:在 Py3.0 中,cmp 参数被完全删除(作为简化和统一语言的更大努力的一部分,消除富比较和 __cmp__ 方法之间的冲突).

我不明白为什么在 py3.0 中删除了 cmp

考虑这个例子:

<预><代码>>>>def numeric_compare(x, y):返回 x - y>>>排序([5, 2, 4, 1, 3], cmp=numeric_compare)[1, 2, 3, 4, 5]

现在考虑这个版本(推荐并与 3.0 兼容):

def cmp_to_key(mycmp):'将 cmp= 函数转换为 key= 函数'K类(对象):def __init__(self, obj, *args):self.obj = objdef __lt__(自我,其他):返回 mycmp(self.obj, other.obj) <0def __gt__(自己,其他):返回 mycmp(self.obj, other.obj) >0def __eq __(自己,其他):返回 mycmp(self.obj, other.obj) == 0def __le__(自我,其他):返回 mycmp(self.obj, other.obj) <= 0def __ge__(自我,其他):返回 mycmp(self.obj, other.obj) >= 0def __ne__(自我,其他):返回 mycmp(self.obj, other.obj) != 0返回 K>>>排序([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__ 让生活更简单吗?

解决方案

对于两个对象 ab__cmp__ 要求 其中之一 a a == ba >b 是真的.但事实可能并非如此:考虑集合,其中 那些 都不正确的情况很常见,例如{1, 2, 3} vs {4, 5, 6}.

于是介绍了__lt__和朋友.但这让 Python 有两种独立的排序机制,这有点荒谬,所以在 Python 3 中删除了不太灵活的一种.

您实际上不必实现所有六种比较方法.您可以使用 @total_ordering 装饰器,并且只实现 <代码>__lt____eq__.

edit:还要注意,在排序的情况下,key 函数可能比 cmp 更有效:在你给出的例子中,Python 可能需要调用你的Python 比较函数 O(n²) 次.但是 key 函数只需要被调用 O(n) 次,如果返回值是内置类型(因为它经常是),O(n²) 成对比较通过 C.

from 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).

I do not understand the reasoning why cmp is removed in py3.0

consider this example:

>>> def numeric_compare(x, y):
        return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]

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]

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?

解决方案

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}.

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.

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: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆