Jonathan Chang
Jonathan Chang

Reputation: 305

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?

Upvotes: 16

Views: 702

Answers (2)

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22021

According to the documentation, all python comparisons operators has same priority:

There are eight comparison operations in Python. They all have the same priority (which is higher than that of the Boolean operations).

However by wrapping comparisons with the brackets, they start to be the atoms expressions, so statements in brackets evaluated before statements outside, that impacts the order of the evalutation, I will decompose the first "contradictional" case, the all others is similar:

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

Per documentation the priority is the same, so evaluation is next:

1. a is None ? -> False # Because a == 3
2. False == b -> False # Because b == 3
3. False is None

Please see order for the second case below:

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

1. a is None ? -> False # Because a == 3
2. b is None -> False # Because b == 3
3. False is False -> True

Upvotes: 2

RemcoGerlich
RemcoGerlich

Reputation: 31250

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!

Upvotes: 16

Related Questions