Ответ 1
Вы всегда можете "отличить" его
>>> tuple([1, 2]) == (1, 2)
True
Имейте в виду, что Python, в отличие от Javascript, сильно typed, и некоторые (большинство?) нас предпочитают так.
При сравнении кортежа с таким списком, как...
>>> [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, поэтому, пожалуйста, не отвечайте где, но почему это реализовано.)
Вы всегда можете "отличить" его
>>> tuple([1, 2]) == (1, 2)
True
Имейте в виду, что Python, в отличие от Javascript, сильно typed, и некоторые (большинство?) нас предпочитают так.
Нет никаких технических причин, по которым списки не могут сравниться с кортежами; это полностью дизайнерское решение, основанное на семантике. Для доказательства того, что он не связан с безопасностью потоков, вы можете сравнивать списки с другими списками:
>>> 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 Я отмечаю там исключение для множеств и фризонов. И, несомненно, некоторые другие, о которых я не знаю. Языковые дизайнеры - пуристы, за исключением тех случаев, когда это платит за практичность.