Why is it that these statements work as expected when brackets are used:
>>> (True is False) == False
True
>>> True is (False == False)
True
But it returns False
when there are no brackets?
>>> True is False == False
False
Why is it that these statements work as expected when brackets are used:
>>> (True is False) == False
True
>>> True is (False == False)
True
But it returns False
when there are no brackets?
>>> True is False == False
False
Python has a unique transitive property when it comes to the comparison operators. It will be easier to see in a simpler case.
if 1 < x < 2:
# Do something
This does what it looks like. It checks if 1 < x and if x < 2. The same thing is happening in your non-parenthesized code.
>>> True is False == False
False
It is checking whether True is False and False == False, only one of which is true.
Based on python documentation about operator precedence :
Note that comparisons, membership tests, and identity tests, all have the same precedence and have a left-to-right chaining feature as described in the Comparisons section.
So actually you have a chained statement like following :
>>> (True is False) and (False==False)
False
You can assume that the central object will be shared between 2 operations and other objects (False in this case).
And note that its also true for all Comparisons, including membership tests and identity tests operations which are following operands :
in, not in, is, is not, <, <=, >, >=, !=, ==
Example :
>>> 1 in [1,2] == True
False
This is a double inequality which gets expanded as (True is False) and (False == False)
. See for instance What is the operator precedence when writing a double inequality in Python (explicitly in the code, and how can this be overridden for arrays?)
Python interprets multiple (in)equalities the way you would expect in Math:
In Math a = b = c
mean all a = b
, b = c
and a = c
.
So True is False == False
means True == False
and False == False
and True == False
, which is False
.
For boolean constants, is
is equivalent to ==
.
Python performs chaining if it encounters operators of same precedence when evaluating an expression.
comparisons, including tests, which all have the same precedence chain from left to right
The below mentioned operators have the same precedence.
in, not in, is, is not, <, <=, >, >=, <>, !=, ==
So, when Python tries to evaluate the expression True is False == False
, it encounters the operators is
and ==
which have the same precedence, so it performs chaining from left to right.
So, the expression True is False == False
is actually evaluated as:
(True is False) and (False == False)
giving False
as the output.