And*_*Dog 23 python comparison tuples list
将元组与像...一样的列表进行比较时
>>> [1,2,3] == (1,2,3)
False
>>> [1,2,3].__eq__((1,2,3))
NotImplemented
>>> (1,2,3).__eq__([1,2,3])
NotImplemented
Run Code Online (Sandbox Code Playgroud)
... Python并没有像他们那样深入比较它们(1,2,3) == (1,2,3).
那是什么原因呢?是因为可变列表可以随时更改(线程安全问题)还是什么?
(我知道这在CPython中的实现方式,所以请不要回答它在哪里,但为什么要实现它.)
Est*_*ber 26
你总是可以"施放"它
>>> tuple([1, 2]) == (1, 2)
True
Run Code Online (Sandbox Code Playgroud)
请记住,与Javascript不同,Python 是强 类型的,有些(大多数?)我们更喜欢这种方式.
Chr*_* B. 12
列表无法与元组进行比较没有技术原因; 它完全是由语义驱动的设计决策.为了证明它与线程安全无关,您可以将列表与其他列表进行比较:
>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> l1 == l2
True
>>> id(l1) == id(l2)
False
Run Code Online (Sandbox Code Playgroud)
允许用户直接比较列表和元组似乎是合理的,但最后你会得到其他问题:是否允许用户比较列表和队列?那两个提供迭代器的对象怎么样?以下怎么样?
>>> s = set([('x', 1), ('y', 2)])
>>> d = dict(s)
>>> s == d # This doesn't work
False
Run Code Online (Sandbox Code Playgroud)
它可以很快变得复杂.语言设计者认识到这个问题,并通过简单地防止不同的集合类型直接相互比较来避免它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
Run Code Online (Sandbox Code Playgroud)
这具有处理任何两个序列的优点,复杂性明显降低.
1我注意到套和frozensets有一个例外.毫无疑问,其他一些我都不知道.语言设计师是纯粹主义者,除非实际付出代价.