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

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 是强 类型的,有些(大多数?)我们更喜欢这种方式.

  • 这真的是最好的方式. (2认同)
  • 我想我们大多数人都喜欢这样. (2认同)
  • @Paul Hankin:强制规则是一件奇怪的事情.算术强制是可以容忍的.由于必须发明的特殊规则,更复杂的非标量类型转换几乎是不可能的. (2认同)
  • @S.Lott 那么 str/unicode 或 set/frozenset 呢?set 和frozenset 的关系不是和list 和tuple 的关系完全一样吗? (2认同)
  • 强类型与它无关.在Python中,int 4和float 4.0具有不同的类型,但被认为代表相同的*值,*因此它们相等.Clojure也是一种强类型语言,它认为序列'(1 2 3)和向量[1 2 3]具有相同的值,尽管它们具有不同的类型 - 它们是相同数据的不同内部表示.Python碰巧选择了计算更快,更容易实现的集合平等方法.但这两种方法都没有比其他方法更"强类型". (2认同)

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

  • 要比较两个序列,不需要跳过next/StopIteration箍.all(i1 = i2表示i1,i2表示itertools.izip_longest(iter1,iter2,fillvalue = object())) (4认同)