Яке значення "(1,) == 1" в Python?


119

Я тестую структуру кортежу, і мені здалося, що це дивно, коли я використовую ==оператор, наприклад:

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

Коли я присвоюю ці два вирази змінній, результат істинний:

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

На мою думку, це питання відрізняється від правила синтаксису трійки комах у формі кордону Python . Я запитую групу виразів між ==оператором.


16
Дивлячись на попереднє запитання ОП лише 2 години тому, здається чудовим (або дивним) те, як саме постановка питання по-різному може призвести до різних результатів (і прийняття серед громади).
АКС

24
@AKS Це різні питання
kmaork

7
@AKS Хоча питання тут незначно відрізняються, я повністю згоден з вашою думкою. Ефект стада ака HNQ.
Божевільний

5
@PythonNewHand Дійсно, це цілком прийнятно. Ось чому я додав, що постановка питання по-іншому .
АКС

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())
)])

1
Ще один корисний інструмент dis- у цьому випадку ви побачите два LOAD_CONSTз різними значеннями ( (1,)і 1) та BUILD_TUPLEopp-кодом.
mgilson

153

Це лише пріоритет оператора. Ти перший

(1,) == 1,

такі групи:

((1,) == 1),

тому будується кортеж з одним елементом з результату порівняння кортежу з одним елементом 1,і цілим числом 1для рівності. Вони не рівні, тому ви отримуєте 1-кортеж False,для результату.


61
Насправді, але 1-кортежі мають непарний синтаксис. Загалом, ви б набагато більше здивовані , якщо, наприклад, 1+2, 2==3, 4*7зробив НЕ групу , як (1+2), (2==3), (4*7). На практиці 1-кортежі майже ніколи не використовуються (ну, поза питаннями StackOverflow ;-)).
Тім Пітерс

6
Можливо, "несподіване" було б кращим словом у використанні, ніж "дивним". Мені трохи здається, що я дивлюся на один із тих малюнків, які можуть бути двома речами, залежно від вашої точки зору та фокусу . Оператор рівності настільки великий порівняно з комами, що на ньому легко зосередитись і припустити, що результат буде True/ False. Тепер, коли я розумію, що відбувається, це абсолютно очевидно і розумно.
skrrgwasme

31
І тепер ви знаєте, що означає "дзен Пітона", кажучи, що єдиний очевидний спосіб зробити це "може бути спочатку не очевидним, якщо ви не голландці" ;-)
Тім Пітерс,

7
Це трохи заплутано, коли ви читаєте документ і бачите, що те, що робить кортеж - це кома, а не дужки! Тож у цьому твердженні кома в правій руці не розглядається як частина тесту, але вона розглядається як роздільник! Несподівана поведінка!
Ikra_5

3
Поширена порада щодо виразів - "коли сумніваєтесь, використовуйте дужки". Після цього добре розмістити дужки навколо всіх однократних, хоча вони не є частиною синтаксису кортежу.
nigel222

12

Коли ви робите

>>> (1,) == 1,

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

Замість того, коли ви призначаєте змінні, два рівні кортежі порівнюються один з одним.

Ви можете спробувати:

>>> x = 1,
>>> x
(1,)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.