Почему "True == False is False" оценивается как "ложь"?
Я получаю довольно неожиданное поведение для выражения, которое работает с ==
, но не с is
:
>>> (True == False) is False
True
>>> True == (False is False)
True
>>> True == False is False
False
>>> id(True)
8978640
>>> id(False)
8978192
>>> id(True == False)
8978192
>>> id(False is False)
8978640
Ответы
Ответ 1
Потому что на самом деле, что скованное сравнение, поэтому
True == False is False
эквивалентно
(True == False) and (False is False)
В этом случае это может быть удивительно, но позволяет писать 1 <= x < 4
в отличие от других языков, таких как C.
Ответ 2
Из docs:
x < y <= z эквивалентно x < y и y <= z, за исключением того, что y является оценивается только один раз (но в обоих случаях z вообще не оценивается, когда x < y считается ложным).
В вашем случае True == False is False
эквивалентно True == False and False is False
, поскольку первое условие False
, поэтому оно замыкает и возвращает False
.
>>> dis.dis(lambda : True == False is False)
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_GLOBAL 1 (False)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 2 (==)
11 JUMP_IF_FALSE_OR_POP 21 <---------this step
14 LOAD_GLOBAL 1 (False)
17 COMPARE_OP 8 (is)
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
Ответ 3
Из документации:
5,9. Сравнения
В отличие от C все операции сравнения в Python имеют тот же приоритет, который ниже, чем у любой арифметической, сдвиговой или побитовой операции. Кроме того, в отличие от C, выражения типа < b < c имеют общепринятую в математике интерпретацию:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
Ответ 4
True == False is False
- это цепное сравнение, что означает то же, что и (True == False) and (False is False)
. Поскольку первое сравнение (True==False
) является ложным, результатом сопоставления с привязкой является False.