我正在尝試在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 本質上無序的型別?
最新回復
- 5月前1 #
相似問題
- 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)