Что означает «(1,) == 1» в Python?

119

Я тестирую структуру кортежа, и мне показалось странным, когда я использую такой ==оператор, как:

>>>  (1,) == 1,
Out: (False,)

Когда я назначаю эти два выражения переменной, результат будет истинным:

>>> a = (1,)
>>> b = 1,
>>> a==b
Out: True

На мой взгляд, этот вопрос отличается от правила синтаксиса завершающей запятой кортежа Python . Прошу группу выражений между ==операторами.

Pythoner
источник
16
Глядя на предыдущий вопрос ОП всего 2 часа назад, кажется чудесным (или странным) то, как простая постановка вопроса по-другому может привести к разным результатам (и признанию в сообществе).
AKS,
24
@AKS Это разные вопросы
kmaork
7
@AKS Хотя здесь вопросы несколько отличаются, я полностью согласен с вашей точкой зрения. Эффект стада, известный как HNQ.
Insane
5
@PythonNewHand Действительно, это вполне приемлемо. Вот почему я добавил эту постановку вопроса по-другому .
AKS,
3
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 как у вас фигура? Я бегло просмотрел эти ответы и не увидел ничего, что могло бы охватить эту конкретную ситуацию.
Дэн Гетц

Ответы:

88

Другие ответы уже показали вам, что поведение связано с приоритетом оператора, как описано здесь .

Я собираюсь показать вам, как найти ответ самостоятельно, когда в следующий раз у вас возникнет вопрос, похожий на этот. Вы можете разобрать, как выражение анализирует, используя astмодуль:

>>> import ast
>>> source_code = '(1,) == 1,'
>>> print(ast.dump(ast.parse(source_code), annotate_fields=False))
Module([Expr(Tuple([Compare(Tuple([Num(1)], Load()), [Eq()], [Num(1)])], Load()))])

Из этого мы видим, что код анализируется, как объяснил Тим Петерс :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])
Wim
источник
1
Другой полезный инструмент: disв этом случае вы увидите два LOAD_CONSTс разными значениями ( (1,)и 1) и BUILD_TUPLEкод opp.
mgilson
153

Это просто приоритет оператора. Твой первый

(1,) == 1,

такие группы:

((1,) == 1),

поэтому строит кортеж с одним элементом из результата сравнения одноэлементного кортежа 1,с целым числом 1на равенство. Они не равны, поэтому вы получаете 1-кортеж False,для результата.

Тим Питерс
источник
61
Не совсем, но у 1-кортежей странный синтаксис. В общем, вы бы гораздо более удивлены , если, например, 1+2, 2==3, 4*7сделал не группу , как (1+2), (2==3), (4*7). На практике кортежи с единицами почти никогда не используются (ну, кроме вопросов StackOverflow ;-)).
Тим Питерс
6
Возможно, лучше было бы использовать «неожиданный», чем «странный». Мне кажется, что я смотрю на один из тех рисунков, которые могут быть двумя вещами, в зависимости от вашей точки зрения и внимания . Оператор равенства настолько велик по сравнению с запятыми, что на нем легко сосредоточиться и предположить, что результатом будет True/ False. Теперь, когда я понимаю, что происходит, это совершенно очевидно и разумно.
skrrgwasme
31
И теперь вы знаете, что означает «Дзен Python», говоря, что один очевидный способ сделать это «может быть неочевиден сначала, если вы не голландец» ;-)
Тим Питерс
7
Это немного сбивает с толку, когда вы читаете документ и видите, что кортеж составляет запятая, а не круглые скобки! Таким образом, в этом утверждении запятая в правой руке не рассматривается как часть теста, а считается разделителем! Неожиданное поведение!
Ikra_5
3
Общий совет по поводу выражений - «если сомневаетесь, используйте круглые скобки». После этого хорошо заключать в скобки все кортежи, состоящие из одного элемента, даже если они не являются частью синтаксиса кортежа.
nigel222
12

Когда ты делаешь

>>> (1,) == 1,

он строит кортеж из результата сравнения кортежа (1,) с целым числом и, таким образом, возвращает False.

Вместо этого, когда вы присваиваете переменным, два равных кортежа сравниваются друг с другом.

Можешь попробовать:

>>> x = 1,
>>> x
(1,)
MNG
источник