在Python3.0中,为什么要从sort/sorted中删除cmp参数?

2024-06-16 09:23:18 发布

您现在位置:Python中文网/ 问答频道 /正文

来自python wikiIn 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__让生活更简单?


Tags: andthetokeyselfobjreturndef
2条回答

cmp被删除是因为.sort()sorted()key属性在大多数情况下是优越的。这是C语言的一个延迟,而且启动起来很混乱。在富比较运算符(__lt____gt__等)之后,必须实现单独的__cmp__方法。

您始终可以使用^{}来调整现有的cmp函数。

当然,由于整数已经是可排序的,您的特定示例可以在不使用key函数的情况下实现;只需添加reverse=True

对于自定义类,使用^{} decorator__eq__一个比较运算符方法(例如__lt__,或__gt__,等等)展开为完整的排序实现。

对于两个对象ab__cmp__要求其中一个a < ba == 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

相关问题 更多 >