В Python (я проверил только с Python 3.6, но я считаю, что он должен работать и для многих предыдущих версий):
(0, 0) == 0, 0 # results in a two element tuple: (False, 0)
0, 0 == (0, 0) # results in a two element tuple: (0, False)
(0, 0) == (0, 0) # results in a boolean True
Но:
a = 0, 0
b = (0, 0)
a == b # results in a boolean True
Почему результаты двух подходов различаются? По-разному ли оператор равенства обрабатывает кортежи?
источник
,
связывает меньше»==
.То, что вы видите во всех трех экземплярах, является следствием грамматической спецификации языка и того, как токены, встречающиеся в исходном коде, анализируются для создания дерева синтаксического анализа.
Взгляд на этот низкоуровневый код должен помочь вам понять, что происходит под капотом. Мы можем взять эти операторы python, преобразовать их в байтовый код, а затем декомпилировать их с помощью
dis
модуля:Случай 1:
(0, 0) == 0, 0
(0, 0)
сначала сравнивается с0
первым и оцениваетсяFalse
. Затем создается кортеж с этим последним результатом0
, так что вы получаете(False, 0)
.Случай 2:
0, 0 == (0, 0)
Кортеж строится с
0
первым элементом. Для второго элемента выполняется та же проверка, что и в первом случае, и вычисляется значениеFalse
, поэтому вы получаете(0, False)
.Случай 3:
(0, 0) == (0, 0)
Здесь, как вы видите, вы просто сравниваете эти два
(0, 0)
кортежа и возвращаетесьTrue
.источник
Другой способ объяснить проблему: вы, вероятно, знакомы со словарными литералами.
и литералы массива
и кортежные литералы
но вы не понимаете, что, в отличие от литералов словаря и массива, круглые скобки, которые вы обычно видите вокруг литерала кортежа, не являются частью синтаксиса литерала . Литеральный синтаксис для кортежей - это просто последовательность выражений, разделенных запятыми:
(«exprlist» на языке формальной грамматики Python ).
Теперь, что вы ожидаете от литерала массива
оценить до? Это, вероятно, больше похоже на то, что должно быть таким же, как
что, конечно, оценивается как
[0, False]
. Аналогично, с явно заключенным в скобки литералом кортежаэто не удивительно получить
(0, False)
. Но круглые скобки необязательны;то же самое. И вот почему вы получаете
(0, False)
.Если вам интересно, почему круглые скобки вокруг литерала кортежа являются необязательными, то в значительной степени потому, что было бы неприятно писать деструктурирующие присваивания таким образом:
источник
Добавление пары скобок вокруг порядка выполнения действий может помочь вам лучше понять результаты:
Запятая используется для разделения выражений (конечно, используя круглые скобки, мы можем задать другое поведение). При просмотре перечисленных вами фрагментов запятая
,
разделяет их и определяет, какие выражения будут оцениваться:(0, 0)
Аналогичным образом можно разбить и кортеж . Запятая разделяет два выражения, состоящих из литералов0
.источник
В первом Python создает кортеж из двух вещей:
(0, 0) == 0
, которое оценивается какFalse
0
Во втором - наоборот.
источник
посмотрите на этот пример:
тогда результат:
тогда сравнение выполняется только с первым числом (0 и r) в примере.
источник