18

I'm trying to guess which operator has priority: > (greater than) or == (equal). This is my experiment:

>>> 5 > 4 == 1
False

As far as I know, this has two possible solutions.

>>> (5 > 4) == 1
True
>>> 5 > (4 == 1)
True

Neither one returns False, so how is the first code resolved by Python?

cdonts
  • 9,304
  • 4
  • 46
  • 72

1 Answers1

26

This has to do with operator chaining. Unlike C/C++ and most other languages, Python allows you to chain comparison operators just like you would in normal mathematics. From the 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).

So, this expression:

5 > 4 == 1

is actually interpreted as:

5 > 4 and 4 == 1  # Except that 4 is only evaluated once.

which becomes:

True and False

which is False.


Using parenthesis however changes how Python interprets your comparison. This:

(5 > 4) == 1

becomes:

True == 1

which is True (see below for why). Same goes for:

5 > (4 == 1)

which becomes:

5 > False

which is also True.


Because of PEP 0285, bool was made a subclass of int and True == 1 while False == 0:

>>> issubclass(bool, int)
True
>>> True == 1
True
>>> False == 0
True
>>>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Here's a link to the documentation, just for reference: https://docs.python.org/2/reference/expressions.html#boolean-operations – mp_ Nov 09 '14 at 23:05
  • 2
    @iCodez the interpretation with chaining is 5 > 4 and 4 == 1 – ryanpattison Nov 09 '14 at 23:05
  • Interesting! Thanks a lot. – cdonts Nov 09 '14 at 23:08
  • 1
    "historical reasons" makes it seem like an unintended quirk of backwards compatibility; it's actually [working by design](http://stackoverflow.com/a/6865824/1763356). – Veedrac Nov 10 '14 at 06:52
  • @Veedrac - I always assumed that it was made that way to keep in line with C/C++ bools (yes, I know C didn't have a bool type for awhile, but many people would do something like `typedef enum { false, true } bool;` to achieve the same result). I'll change the wording though since it is really just a way to include the PEP link. :) –  Nov 10 '14 at 16:27