开发者

Python: Why is comparison between lists and tuples not supported?

开发者 https://www.devze.com 2022-12-21 21:30 出处:网络
When comparing a tuple with a list like ... >>> [1,2,3] == (1,2,3) False >>> [1,2,3].__eq__((1,2,3))

When comparing a tuple with a list like ...

>>> [1,2,3] == (1,2,3)
False
>>> [1,2,3].__eq__((1,2,3))
NotImplemented
>>> (1,2,3).__eq__([1,2,3])
NotImplemented

... Python does not deep-compare them as done with (1,2,3) == (1,2,3).

So what is the reason for this? Is it because the mutable list can be changed at any time (thread-safety issues) or what?

(I know where th开发者_如何学Pythonis is implemented in CPython, so please don't answer where, but why it is implemented.)


You can always "cast" it

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

Keep in mind that Python, unlike for example Javascript, is strongly typed, and some (most?) of us prefer it that way.


There's no technical reason for lists not being able to compare to tuples; it's entirely a design decision driven by semantics. For proof that it's not related to thread-safety, you can compare lists to other lists:

>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> l1 == l2
True
>>> id(l1) == id(l2)
False

It seems reasonable to allow users to directly compare lists and tuples, but then you end up with other questions: should the user be allowed to compare lists and queues? What about any two objects which provide iterators? What about the following?

>>> s = set([('x', 1), ('y', 2)])
>>> d = dict(s)
>>> s == d  # This doesn't work
False

It can get complicated pretty quickly. The language designers recognized the issue, and avoided it by simply preventing different collection types from comparing directly with each other1.

Note that the simple solution (to create a new list from the tuple and compare them) is easy but inefficient. If you're working with large numbers of items, you're better off with something like:

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

This has the advantage of working on any two sequences, at an obvious cost in complexity.


1 I note there's an exception for sets and frozensets. And no doubt a few others I'm not aware of. The language designers are purists, except where it pays to be practical.

0

精彩评论

暂无评论...
验证码 换一张
取 消