python - 为什么在 Python3.0 中将 cmp 参数从 sort/sorted 中删除?

标签 python sorting object cmp

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

不明白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__ 而不是 __cmp__ 再次,为什么这个建议?我不能只定义 __cmp__ 让生活更简单吗?

最佳答案

对于两个对象 ab , __cmp__要求 其中一个 a < b , a == b , 和 a > b是真的。但情况可能并非如此:考虑集合,其中 没有一个 是非常常见的,例如{1, 2, 3}{4, 5, 6} .

所以 __lt__和 friend 介绍了。但这给 Python 留下了两个独立的排序机制,这有点荒谬,所以在 Python 3 中删除了不太灵活的排序机制。

您实际上不必实现所有六种比较方法。您可以使用 @total_ordering decorator并且只执行 __lt____eq__ .

编辑:还要注意,在排序的情况下,key函数可能比 cmp 更有效:在您给出的示例中,Python 可能必须调用您的 Python 比较函数 O(n²) 次。但是一个key函数只需要调用 O(n) 次,如果返回值是内置类型(通常是这样),则 O(n²) 成对比较通过 C 进行。

关于python - 为什么在 Python3.0 中将 cmp 参数从 sort/sorted 中删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20202418/

相关文章:

python - 多对多字段的 Django ModelForm

Python 3 按值对字典列表进行排序,其中值以字符串开头

javascript - 按对象属性的键对对象数组进行排序

Javascript更新对象属性值

iphone - 如何在 iphone 的 NSDictionary 中设置数组值和键?

php - PHP 中的数组到对象和对象到数组 - 有趣的行为

python - 树中的生产者和消费者队列

python - Pepper Linux 日志日期格式看起来毫无意义

python - panda 根据其他列的值同时添加几个新列?

javascript - 插入一个新数组并在 JavaScript 中过滤冗余对象