Sha*_*itt 11 python sorting list python-3.x
问候Pythonic世界.学习Python 3.3的第4天,我遇到了一个奇怪的属性list.sort
.
我创建了一个包含五个元素的列表:四个字符串,中间有一个数字.list.sort
由于混合类型,试图开始工作给出了预期的错误:
>>> list = ['b', 'a', 3, 'd', 'c']
>>> list.sort()
Traceback (innermost last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>> list
['b', 'a', 3, 'd', 'c']
Run Code Online (Sandbox Code Playgroud)
列表没有变化.
但后来我把数字移到了最后,再次使用了list.sort,得到了这个:
>>> list = ['b', 'a', 'd', 'c', 3]
>>> list.sort()
Traceback (innermost last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
>>> list
['a', 'b', 'c', 'd', 3]
Run Code Online (Sandbox Code Playgroud)
好的,一个错误.但是这个列表已经自行排序,将数字踢到最后.我在这个网站或Langtangen找不到任何解释.这种行为有一些潜在的原因吗?在某些情况下它会有用吗?
Rya*_*ing 11
从Python 3 文档:
此方法仅使用<项之间的比较对列表进行排序.不会禁止异常 - 如果任何比较操作失败,整个排序操作将失败(并且列表可能会处于部分修改状态).
文档并不特别保证任何行为,但元素很可能会被部分排序.它们在发生异常时所处的顺序,并且该顺序可以在实现之间变化,或者可能(但不太可能)两次后续运行程序.
如果您想尝试对项目进行排序而不必担心不幸的重新排序,您可以使用sorted
内置函数,它将返回一个新列表而不是修改原始列表.
>>> seq = ['b', 'a', 3, 'd', 'c']
>>> try:
... seq = sorted(seq) # if sorted fails, result won't be assigned
... except Exception: # you may only want TypeError
... pass
...
>>> seq
['b', 'a', 3, 'd', 'c'] # list unmodified
Run Code Online (Sandbox Code Playgroud)
编辑: 解决每个人都说的话
一旦它看到两种不同的类型,就会引发异常
我知道你可能已经意识到这种说法过于简单了,但我认为不清楚,这会引起混淆.
以下示例由两个类A
和B
支持通过各自相互比较__lt__
方法.它显示了这两种类型的混合列表,这些类型按list.sort()
排序顺序打印,然后按排序顺序打印,没有异常引发:
class A:
def __init__(self, value):
self.a = value
def __lt__(self, other):
if isinstance(other, B):
return self.a < other.b
else:
return self.a < other.a
def __repr__(self):
return repr(self.a)
class B:
def __init__(self, value):
self.b = value
def __lt__(self, other):
if isinstance(other, A):
return self.b < other.a
else:
return self.b < other.b
def __repr__(self):
return repr(self.b)
seq = [A(10), B(2), A(8), B(16), B(9)]
seq.sort()
print(seq)
Run Code Online (Sandbox Code Playgroud)
这个输出是:
[2, 8, 9, 10, 16]
Run Code Online (Sandbox Code Playgroud)
了解每一个细节并不重要.这只是为了说明list.sort()
如果所有部分都在那里,混合类型列表可以使用
我通过假设我知道列表中的数据类型来写下面的答案,可能效率不高。我的想法是根据数据类型将给定的列表划分为子列表,然后对每个单独的列表进行排序并组合。
input= ['b', 'a', 3, 'd', 'c']
strs = list(filter(lambda x : type(x) ==str,input))
ints = list(filter(lambda x: type(x) == int, input))
output = sorted(strs) + sorted(ints)
Run Code Online (Sandbox Code Playgroud)