Python: Почему сравнение между списками и кортежами не поддерживается?

При сравнении кортежа со списком вроде …

>>> [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, поэтому, пожалуйста, не отвечайте где , но почему это реализовано.)

2 Solutions collect form web for “Python: Почему сравнение между списками и кортежами не поддерживается?”

Вы всегда можете «бросить» его

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

Имейте в виду, что Python, в отличие от Javascript, строго типизирован , и некоторые (большинство?) Из нас предпочитают это именно так.

Нет никаких технических причин, по которым списки не могут сравниться с кортежами; это полностью дизайнерское решение, основанное на семантике. Для доказательства того, что это не связано с безопасностью потоков, вы можете сравнивать списки с другими списками:

 >>> 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 

Это имеет преимущество в работе над любыми двумя последовательностями с очевидной стоимостью по сложности.


Я отмечаю, что есть исключения для множеств и фризонов. И, несомненно, некоторые другие, о которых я не знаю. Дизайнеры языка – пуристы, за исключением случаев, когда это платит за практичность.

  • Python, должен ли я реализовать __ne __ () оператор на основе __eq__?
  • Значение для epsilon в Python
  • Python - учение против unittest
  • Почему 4 <'3' возвращает True в Python 2?
  • Как сравнить два объекта JSON с одинаковыми элементами в другом порядке равными?
  • Как набор Python () проверяет, совпадают ли два объекта? Какие методы должен определить объект для его настройки?
  • Python - лучший язык программирования в мире.