21

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?

Aguy
  • 7,851
  • 5
  • 31
  • 58

2 Answers2

21

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 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).

0 is 0 is true because Python interns small integers, an implementation detail, so you get (True) and (True) producing True.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
7

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).

sepp2k
  • 363,768
  • 54
  • 674
  • 675