This baffles me. Even without knowing the precedence order, one can check that the two possible ways to gather the expression would give False
:
>>> (0 is 0) == 0
False
>>> 0 is (0 == 0)
False
But
>>> 0 is 0 == 0
True
How come?
This baffles me. Even without knowing the precedence order, one can check that the two possible ways to gather the expression would give False
:
>>> (0 is 0) == 0
False
>>> 0 is (0 == 0)
False
But
>>> 0 is 0 == 0
True
How come?
You are using comparison operator chaining. The expression is interpreted as:
(0 is 0) and (0 == 0)
From the Comparisons documentation:
Comparisons can be chained arbitrarily, e.g.,
x < y <= z
is equivalent tox < y and y <= z
, except thaty
is evaluated only once (but in both casesz
is not evaluated at all whenx < y
is found to be false).
0 is 0
is true because Python interns small integers, an implementation detail, so you get (True) and (True)
producing True
.
When chaining comparison operators in Python, the operators aren't actually applied to the result of the other operators, but are applied to the operands individually. That is x ? y ?? z
(where ?
and ??
are supposed to stand in for some comparison operators) is neither equivalent to (x ? y) ?? z
nor x ? (y ?? z)
, but rather x ? y and y ?? z
.
This is particularly useful for >
and co., allowing you to write things like min < x < max
and have it do what you want rather than comparing a boolean to a number (which would happen in most other languages).