当前位置: 首页 > 面试题库 >

为什么从Python3.0中的sort / sorted中删除了cmp参数?

楚钊
2023-03-14
问题内容

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


问题答案:

对于两个物体ab__cmp__要求 之一 a < ba == ba > 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。



 类似资料:
  • 为什么已经从PHP中删除了,还有其他原因吗?

  • 将jmeter测试集设置为使用10个线程组运行8小时,每个线程组具有不同的线程数,还使用每个线程组具有不同TPS速率的吞吐量成形计时器;在一段随机时间(大多数时间在6小时后)后,其中一个线程组终止活动线程,我尝试了不同的配置以及穿透输出成形计时器,比如使用Concurrency线程组和循环控制器,但结果是相同的;这是我在日志中看到的: 我们感谢您为解决此问题提供的任何帮助。

  • Spring 4:https://docs.Spring.io/autorepo/docs/Spring/4.2.4.release/javadoc-api/org/springframework/web/context/request/requestattributes.html#scope_global_session Spring 5:https://docs.Spring.io/autor

  • 为什么我无法从mapview中删除我的注释? 我的代码: <代码>[self.mapView removeAnnotation:myAnnotation] 不适用于我

  • 问题内容: Java在Java 5中引入了带有泛型的类型擦除,因此它们可以在Java的旧版本上使用。这是兼容性的折衷。从那以后,我们就失去了兼容性–字节码可以在JVM的更高版本上运行,但不能在较早的版本上运行。这似乎是最糟糕的选择:我们丢失了类型信息,并且仍然无法在较旧版本上运行针对较新版本JVM编译的字节码。发生了什么? 具体来说,我是在问是否存在任何技术原因,导致无法在下一版JVM中删除类型擦

  • 我点击图片,弹出效果很好。但是,当我在弹出窗口外单击时,iframe allowfullscreen和frameborder属性将被删除。我再次点击弹出窗口,全屏工作,有一条白线。我希望弹出停止视频播放一旦关闭和iframe返回没有src和保留其属性。 我试过: 使用JavaScript/jQuery更新属性 通过JavaScript/jQuery替换html(已注释掉) HTML