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,444
  • 4
  • 28
  • 54

2 Answers2

20

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
  • 963,270
  • 265
  • 3,804
  • 3,187
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
  • 353,842
  • 52
  • 662
  • 667