Because in fact that’s a chained comparison, so
True == False is False
is equivalent to
(True == False) and (False is False)
This can be surprising in this case, but lets you write 1 <= x < 4
unlike in other languages like C.
From the docs:
x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
In your case True == False is False
is equivalent to True == False and False is False
as the first condition is False
so it short-circuits and return 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
answered Jun 19 '13 at 22:11
Ashwini ChaudharyAshwini Chaudhary
199k43 gold badges379 silver badges427 bronze badges
From the documentation:
5.9. Comparisons
Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a < b < c have the interpretation that is conventional in mathematics:
comparison ::= or_expr ( comp_operator or_expr )*
comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
| "is" ["not"] | ["not"] "in"
True == False is False
is a chained comparison, which means the same as (True == False) and (False is False)
. Since the first comparison (True==False
) is false, the result of the chained comparison is False.