Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 772
Jonathan Chang Avatar asked Aug 27 '18 18:08

Jonathan Chang


People also ask

What is the operator precedence in Python?

Operator precedence in Python simply refers to the order of operations. Operators are used to perform operations on variables and values. Python classifies its operators in the following groups: Arithmetic operators.

Which operator has more precedence in Python?

Python follows the same precedence rules for its mathematical operators that mathematics does. Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want.


2 Answers

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!

like image 62
RemcoGerlich Avatar answered Oct 08 '22 06:10

RemcoGerlich


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
like image 23
Andriy Ivaneyko Avatar answered Oct 08 '22 06:10

Andriy Ivaneyko