Python:为什么不支持列表和元组之间的比较?

时间:2010-02-26 21:53:52

标签: python list comparison tuples

将元组与像......这样的列表进行比较时。

>>> [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 ,但为什么实现它。)

2 个答案:

答案 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有一个例外。毫无疑问,其他一些我都不知道。语言设计师是纯粹主义者,除非实际付出代价。