将元组与像......这样的列表进行比较时。
>>> [1,2,3] == (1,2,3)
False
>>> [1,2,3].__eq__((1,2,3))
NotImplemented
>>> (1,2,3).__eq__([1,2,3])
NotImplemented
... Python并没有像(1,2,3) == (1,2,3)
那样深入比较它们。
那么这是什么原因?是因为可变列表可以随时更改(线程安全问题)还是什么?
(我知道这在CPython中的实现方式,所以请不要回答 where ,但为什么实现它。)
答案 0 :(得分:21)
你总是可以“施放”它
>>> tuple([1, 2]) == (1, 2)
True
请记住,Python不像Javascript,is strongly typed,而且有些(大多数?)我们更喜欢这种方式。
答案 1 :(得分:10)
没有技术理由让列表无法与元组进行比较;它完全是由语义驱动的设计决策。为了证明它与线程安全无关,您可以将列表与其他列表进行比较:
>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> l1 == l2
True
>>> id(l1) == id(l2)
False
允许用户直接比较列表和元组似乎是合理的,但最后你会得到其他问题:是否允许用户比较列表和队列?那两个提供迭代器的对象怎么样?以下怎么样?
>>> s = set([('x', 1), ('y', 2)])
>>> d = dict(s)
>>> s == d # This doesn't work
False
它可以很快变得复杂。语言设计者认识到这个问题,并通过简单地防止不同的集合类型直接相互比较来避免它 1 。
请注意,简单的解决方案(从元组创建新列表并进行比较)很容易但效率低下。如果您正在处理大量项目,那么最好使用以下内容:
def compare_sequences(iter1, iter2):
iter1, iter2 = iter(iter1), iter(iter2)
for i1 in iter1:
try:
i2 = next(iter2)
except StopIteration:
return False
if i1 != i2:
return False
try:
i2 = next(iter2)
except StopIteration:
return True
return False
这具有处理任何两个序列的优点,复杂性明显降低。
1 我注意到sets和frozensets有一个例外。毫无疑问,其他一些我都不知道。语言设计师是纯粹主义者,除非实际付出代价。