首页>Program>source

我正在尝试在3.x中复制(如果可能要改进)Python 2.x的排序行为,以使诸如 int之类的可相互排序的类型 , float 等等按预期排序,并且相互不可排序的类型在输出中分组。

这是我所谈论的例子:

>>> 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()

还有另一种方法可以解决 both 任意,独特但互有序类型的问题 and 本质上无序的类型?

最新回答
  • 2021-1-11
    1 #

    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)

  • rust:什么时候在一个结构中定义多个生存期有用?
  • javascript:for循环中的闭包