Search code examples
pythonpython-3.xoperator-precedencenonetype

Python is, == operator precedence


In Python3,

a = b = 3
a is None == b is None

returns False, but

(a is None) == (b is None)

returns True. So I would assume based on this example alone, == has precedence over is.

However,

a = b = None
a is None == b is None

returns True. And

(a is None) == (b is None)

returns True. But

a is (None == b) is None

returns False. In this case, it would seem as if is has precedence over ==.

To give another example, and this expression isn't meant to do anything, but bear with me please. If I say

None is None == None

it returns True. But both of the following return False.

None is (None == None)
(None is None) == None

So clearly, Python isn't evaluating these with some strict precedence, but I'm confused what is going on. How is it evaluating this expression with 2 different operators, but differently from either order?


Solution

  • What you see here is operator chaining and there is no precedence involved at all!

    Python supports expressions like

    1 < a < 3
    

    To test that a number is in between 1 and 3; it's equal to (1 < a) and (a < 3) except that a is only evaluated once.

    Unfortunately that also means that e.g.

    None is None == None
    

    actually means

    (None is None) and (None == None)
    

    which is of course True, and the longer example you started with

    a = b = 3
    a is None == b is None
    

    means

    (a is None) and (None == b) and (b is None)
    

    which can only be True if both a and b are None.

    Documentation here, see the bit about chaining.

    Very useful sometimes but it also pops up when you least expect it!