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

如何在Python 3.x中获得类似2.x的排序行为?

谷梁嘉悦
2023-03-14
问题内容

我试图复制(如果可能改善)的Python
2.x的在3.x的排序行为,使双方订购类型喜欢intfloat等如预期进行排序,并相互unorderable类型的输出中进行分组。

这是我正在谈论的示例:

>>> sorted([0, 'one', 2.3, 'four', -5])  # Python 2.x
[-5, 0, 2.3, 'four', 'one']



>>> sorted([0, 'one', 2.3, 'four', -5])  # Python 3.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()

我之前在此方面的尝试(使用键参数的类)sorted()从根本上被破坏了,因为它的方法是

  1. 试图比较值,以及
  2. 如果失败,则退回比较其类型的字符串表示形式

正如布伦·巴恩(BrenBarn)的出色回答所解释的那样,这可能导致不及物动词的排序。

我最初拒绝甚至不尝试编写代码的简单方法是使用返回(type, value)元组的键函数:

def motley(value):
    return repr(type(value)), value

但是,这不能满足我的要求。首先,它打破了相互可排序类型的自然排序:

>>> sorted([0, 123.4, 5, -6, 7.89])
[-6, 0, 5, 7.89, 123.4]
>>> sorted([0, 123.4, 5, -6, 7.89], key=motley)
[7.89, 123.4, -6, 0, 5]

其次,当输入包含两个本质上不可排序的对象时,它将引发异常:

>>> sorted([{1:2}, {3:4}], key=motley)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < dict()

…这当然是Python 2.x和3.x的标准行为-
但理想情况下,我希望将这些类型组合在一起(我并不特别在意它们的顺序,但似乎与之保持一致Python保证稳定排序,确保它们保留原始顺序。

我可以通过特殊包装解决数字类型的第一个问题:

from numbers import Real
from decimal import Decimal

def motley(value):
    numeric = Real, Decimal
    if isinstance(value, numeric):
        typeinfo = numeric
    else:
        typeinfo = type(value)
    return repr(typeinfo), value

…一直有效:

>>> sorted([0, 'one', 2.3, 'four', -5], key=motley)
[-5, 0, 2.3, 'four', 'one']

…但是没有考虑到可能存在其他相互区分的(可能是用户定义的)不同类型的事实,当然,对于本质上不可排序的类型,仍然会失败:

>>> sorted([{1:2}, {3:4}], key=motley)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < dict()

是否有其他方法解决了 两个 任意的,不同的,但是,相互订购类型的问题 ,并 认为本质unorderable类型的?


问题答案:

愚蠢的想法:首先将所有不同的项目划分为可以相互比较的组,对各个组进行排序,最后将它们连接起来。我假设某项目与某组的第一个成员具有可比性,那么该项目可与该组的所有成员具有可比性。像这样的东西(Python3):

import itertools

def python2sort(x):
    it = iter(x)
    groups = [[next(it)]]
    for item in it:
        for group in groups:
            try:
                item < group[0]  # exception if not comparable
                group.append(item)
                break
            except TypeError:
                continue
        else:  # did not break, make new group
            groups.append([item])
    print(groups)  # for debugging
    return itertools.chain.from_iterable(sorted(group) for group in groups)

在可悲的情况下,这将是二次运行时间,所有项目都不具有可比性,但是我想唯一确定的方法是检查所有可能的组合。对于试图对一长串无法排序的项(例如复数)进行排序的人,将二次行为视为应受的惩罚。在一些字符串和一些整数混合的更常见情况下,速度应类似于普通排序的速度。快速测试:

In [19]: x = [0, 'one', 2.3, 'four', -5, 1j, 2j,  -5.5, 13 , 15.3, 'aa', 'zz']

In [20]: list(python2sort(x))
[[0, 2.3, -5, -5.5, 13, 15.3], ['one', 'four', 'aa', 'zz'], [1j], [2j]]
Out[20]: [-5.5, -5, 0, 2.3, 13, 15.3, 'aa', 'four', 'one', 'zz', 1j, 2j]

这似乎也是一种“稳定的排序”,因为这些组是按照遇到无与伦比的项目的顺序形成的。



 类似资料:
  • 以下Python3.x整数乘法的平均运算时间在1.66s到1.77s之间: 如果将替换为,则需要在和之间。怎么会呢? 另一方面,在Java中则相反:在Java中更快。Java测试链接:为什么在Java中2*(i*i)比2*i*i快? 我运行每个版本的程序10次,以下是结果。

  • 我们在桌面应用程序中大量使用flexbox,比如寻找网络应用程序,它一直运行良好。 但是在最新的火狐开发者版(35.0a2)中,布局并不像预期的那样(它会超出视口):http://tinyurl.com/k6a8jde 这在Firefox33.1中运行良好。 我认为这与此处描述的flexbox更改有关:https://developer.mozilla.org/en-US/Firefox/Rele

  • 问题内容: 我在计算机上得到以下结果: 我认为这可能与int / long转换有关,但在2.7中并没有更快的速度。 问题答案: Python 2使用朴素的阶乘算法: Python 3使用分治法阶乘算法: 有关讨论,请参见Python Bugtracker问题。感谢DSM指出这一点。

  • "https://cn.investing.com/indices/hnx-30-components",这个网页包含了hnx30公司的构成,我只要爬取下来,用一个字典来容纳结果,键是公司名,值是一个链接,点击这个链接,可以跳转到公司名的网页,这个公司名对应的symbol就在里面。 下面我要做的是,获得每个公司的symbol,发现,居然无法用playwright,来模拟跳转,并获取跳转后的网页,请

  • 我将应用程序迁移到了laravel 5.7。在composer.json中安装软件包时,我将“maatwebsite/excel:~2.1.0”升级到“maatwebsite/excel”:“^3.1”。因此,现在我的导出功能不再工作。我尝试在中跟踪升级https://docs.laravel-excel.com/3.1 但不适用于我。这是旧版本中使用的旧代码:

  • 我试图实现一个解决方案使用SDN的目的是创建一个动态密码,其中我的标签变化W.R.T输入类型(n类型)与节点的属性无关。 希望一个类似于这个链接上提到的sollation能帮助我。是否可以使用GraphRepository模式动态构造neo4j密码查询 如果您确实使用了Neo4jTemplate,那么您应该针对它的Neo4jOperations接口而不是template类编写代码。 下表显示了为S