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

2024-05-19 13:32:11 发布

您现在位置:Python中文网/ 问答频道 /正文

你好,Python世界。在学习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]

好吧,一个错误。但名单已经自行排序,把数字踢到了最后。我找不到任何解释,在这个网站或在蓝塘根。这种行为有什么潜在的原因吗?在某些情况下有用吗?


Tags: in错误stdinline数字sortlistfile
3条回答

我在下面写的答案是,假设我知道列表中的数据类型,可能效率不高。我的想法是根据数据类型将给定的列表划分为子列表,然后对每个列表进行排序并合并。

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)

从Python 3docs

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

我知道你可能意识到这种说法过于简单化,但我认为如果不说清楚,就会造成混乱。

下面的示例由两个类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()一起工作

这并不罕见。简单地说,sort()不要检查列表是否包含一致的数据类型,而是它尝试对进行排序。所以一旦你的元素结束了,它会在最近被分析,所以算法在之前对列表的一部分进行了排序,发现了一个错误。

不-它没有用处,因为它在很大程度上依赖于实现的排序机制。

相关问题 更多 >