我正在尝试在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()
的关键参数
(看到
为什么用于排序异构序列的键类的行为异常?)从根本上被破坏了,因为它的方法
- 尝试比较值,并且
- 如果失败,则退回比较其类型的字符串表示形式
可能导致不及物的顺序,如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-111 #
相关问题
- python:素因数分解-列表pythonpython3.xprimefactoring2021-01-12 01:25
- windows下适用于Python 3x的OpenCVpythonwindowsopencvpython3.x2021-01-11 22:58
- python:TypeError:worker()接受0个位置参数,但给出了1个pythonpython3.x2021-01-11 22:58
- python:标识符中的字符无效pythonpython3.x2021-01-11 20:56
- python:自然排序Pandas DataFramepythonpython2.7sortingpandasnatsort2021-01-11 18:56
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)