Why does the expression 0 < 0 == 0 return False in Python?
I believe Python has special case handling for sequences of relational operators to make range comparisons easy to express. It's much nicer to be able to say 0 < x <= 5
than to say (0 < x) and (x <= 5)
.
These are called chained comparisons. And that's a link to the documentation for them.
With the other cases you talk about, the parentheses force one relational operator to be applied before the other, and so they are no longer chained comparisons. And since True
and False
have values as integers you get the answers you do out of the parenthesized versions.
Why in Python does 0, 0 == (0, 0) equal (0, False)?
The first two expressions both parse as tuples:
(0, 0) == 0
(which isFalse
), followed by0
0
, followed by0 == (0, 0)
(which is stillFalse
that way around).
The expressions are split that way because of the relative precedence of the comma separator compared to the equality operator: Python sees a tuple containing two expressions, one of which happens to be an equality test, instead of an equality test between two tuples.
But in your second set of statements, a = 0, 0
cannot be a tuple. A tuple is a collection of values, and unlike an equality test, assignment has no value in Python. An assignment is not an expression, but a statement; it does not have a value that can be included into a tuple or any other surrounding expression. If you tried something like (a = 0), 0
in order to force interpretation as a tuple, you would get a syntax error. That leaves the assignment of a tuple to a variable – which could be made more explicit by writing it a = (0, 0)
– as the only valid interpretation of a = 0, 0
.
So even without the parentheses on the assignment to a
, both it and b
get assigned the value (0,0)
, so a == b
is therefore True
.
0 is 0 == 0 (#evaluates to True?)
When chaining comparison operators in Python, the operators aren't actually applied to the result of the other operators, but are applied to the operands individually. That is x ? y ?? z
(where ?
and ??
are supposed to stand in for some comparison operators) is neither equivalent to (x ? y) ?? z
nor x ? (y ?? z)
, but rather x ? y and y ?? z
.
This is particularly useful for >
and co., allowing you to write things like min < x < max
and have it do what you want rather than comparing a boolean to a number (which would happen in most other languages).
Why does print(3 > 0 == True) show False?
What happens is this:
The value 3 > 0 == True
is interpreted as (3>0) AND (0==True)
which gives True AND False
which is of course False
This is why for example the statement: 3 > 1 == True
evaluates to True
Why does `True == False is False` evaluate to False?
Because in fact that's a chained comparison, so
True == False is False
is equivalent to
(True == False) and (False is False)
This can be surprising in this case, but lets you write 1 <= x < 4
unlike in other languages like C.
Why does (0>1 + 0>9) return False, but ((0>1) + (0>9)) return 0?
>>> ((0>1) + (0>9))
0
This is integer addition, since False
is an integer instance. bool
doesn't define addition, so False + False
is resolved on the parent class int.__add__
.
>>> (0>1 + 0>9)
False
This is a chained comparison, it's 0 > 1 > 9
in disguise.
>>> (0>1 + (0>9))
False
This is a regular comparison, it's 0 > 1 + False
in disguise.
Related Topics
Find If 24 Hrs Have Passed Between Datetimes
How to Find Overlapping Matches With a Regexp
How to Create a Daemon in Python
Performant Cartesian Product (Cross Join) With Pandas
How to Retrieve a Module'S Path
How to Read a Text File into a String Variable and Strip Newlines
How to Call a Function Within a Class
How to Merge Dictionaries of Dictionaries
About the Changing Id of an Immutable String
Why Does This Iterative List-Growing Code Give Indexerror: List Assignment Index Out of Range
Display Number With Leading Zeros
Random String Generation With Upper Case Letters and Digits
How to Get the Value of a Variable Given Its Name in a String
Install a Python Package into a Different Directory Using Pip
Iterating Through a Range of Dates in Python