Python:list.sort() 查询当列表包含不同元素类型时

标签 python list sorting 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']

列表不变。

但后来我把数字移到最后,再次使用 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]

好的,一个错误。但是列表已经自行排序,将数字踢到最后。我在此站点或 Langtangen 中找不到对此的任何解释。这种行为是否有一些潜在的原因?它在某些情况下有用吗?

最佳答案

来自 Python 3 docs :

This method sorts the list in place, using only < comparisons between items. Exceptions are not suppressed - if any comparison operations fail, the entire sort operation will fail (and the list will likely be left in a partially modified state).

文档不保证任何特定的行为,但元素很可能会中途排序。无论异常发生时它们的顺序如何,这个顺序可能因实现而异,或者可能(但不太可能)程序的两次后续运行。

如果您想尝试对项目进行排序而不担心不幸的重新排序,您可以使用 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

编辑: 对每个人都说类似的话

once it sees two different types it raises an exception

我知道您可能已经意识到这种说法过于简单化了,但我认为如果不清楚的话,会造成混淆。举一个明显的例子,您可以混合使用 intfloat 对列表进行排序。

以下示例由两个类 AB 组成,它们支持通过各自的 __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)

这个的输出是:

[2, 8, 9, 10, 16]

了解其中的每一个细节并不重要。这只是为了说明混合类型的列表可以使用 list.sort() 如果所有部分都在那里

关于Python:list.sort() 查询当列表包含不同元素类型时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20872314/

相关文章:

Python 读取文件。每行制作一个列表

python - 在 Python 中生成多元分布(数据点)

python - 使用Python计算一定时间间隔内的随机数

java - 使用 Jackson 反序列化包装列表

ios - 将分布在屏幕边缘的可移动 UILabel 保存到有序数组中

templates - D 模板 : Sort a list of types

python - 在 python 中对多维 JSON 对象进行排序

python - 如何加速Python中集合字典的交集

python - 将简单标记的结果放入变量中

C# - 实时显示多行文本框计数