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.