【问题标题】:Python: Why is comparison between lists and tuples not supported?Python:为什么不支持列表和元组之间的比较?
【发布时间】:2010-02-26 21:53:52
【问题描述】:

当比较一个元组和一个类似...的列表时

>>> [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中实现的,所以请不要回答在哪里,而是为什么实现它。)

【问题讨论】:

标签: python list comparison tuples


【解决方案1】:

你总是可以“施放”它

>>> tuple([1, 2]) == (1, 2)
True

请记住,Python 与 Javascript、is strongly typed 不同,我们中的一些人(大多数?)更喜欢这种方式。

【讨论】:

  • 我认为我们大多数人都喜欢这样。
  • 我认为强类型的想法在这里真正重要,所以我会接受你的正确答案。
  • @Paul Hankin:强制规则是一件奇怪的事情。算术强制是勉强可以容忍的。更复杂的非标量类型转换几乎不可能证明是合理的,因为必须发明一些临时规则。
  • @S.Lott 那么 str/unicode 或 set/frozenset 呢? set和frozenset的关系不就和list和tuple的关系完全一样吗?
  • 强类型与它无关。在 Python 中,int 4 和 float 4.0 具有不同的类型,但被认为表示相同的 值,,因此它们比较相等。 Clojure 也是一种强类型语言,它认为序列 '(1 2 3) 和向量 [1 2 3] 具有相同的值,尽管它们的类型不同——它们是相同数据的不同内部表示. Python 碰巧选择了一种计算速度更快、更易于实现的方法来实现集合相等性。但是这两种方法都不比另一种更“强类型”。
【解决方案2】:

列表无法与元组进行比较没有技术原因;这完全是由语义驱动的设计决策。为了证明它与线程安全无关,您可以将列表与其他列表进行比较:

>>> 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 我注意到集合和冻结集合有一个例外。毫无疑问,还有一些我不知道的。语言设计者是纯粹主义者,除非是为了实用。

【讨论】:

  • 要比较两个序列,无需跳过 next/StopIteration 循环。 all(i1 == i2 for i1, i2 in itertools.izip_longest(iter1, iter2, fillvalue=object()))
猜你喜欢
  • 1970-01-01
  • 2012-04-24
  • 2017-04-18
  • 2020-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
相关资源
最近更新 更多