mdml
mdml

Reputation: 22902

Order of evaluation when testing equivalence of booleans

I just encountered the following and am curious about Python's behavior:

>>> x = 1
>>> x in range(2)
True
>>> type(x in range(2))
<type 'bool'>
>>> x in range(2) == True
False
>>> x in range(2) == False
False
>>> (x in range(2)) == True
True

In particular, why does (1 in range(2)) == True evaluate True and l in range(2) == True evaluate to False? It seems like there is some strange order of evaluation behavior in the latter, except that if you make the order explicitly wrong, you get a TypeError:

>>> x in (range(2) == True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'bool' is not iterable

For the record, I don't know any cases where I would use x in range(2) == True instead of just x in range (2), but would just like to know why this is happening. I also tested this in both Python2.7 and Python3, and the behavior is the same.

Upvotes: 5

Views: 118

Answers (3)

jramirez
jramirez

Reputation: 8685

I think is becuause you are actually just evaluating the range(2) part which if you try it in the interpreter you get this.

>>> range(2) == True
>>> False

Upvotes: -1

Martijn Pieters
Martijn Pieters

Reputation: 1123560

The == equality and in membership operators are both comparison operators, and these can be chained.

Chaining takes the form of expr1 op1 expr2 op2 expr3, which is interpreted as (expr1 op1 expr2) and (expr2 op2 expr3) but the middle expr2 is only evaluated once.

So, your examples are really:

x in range(2) and range(2) == True

and range(2) is never equal to a boolean value.

Note that you should really never compare to == True or == False. Leave that to while or if to test for you.

Upvotes: 3

Rohit Jain
Rohit Jain

Reputation: 213321

The below expression:

x in range(2) == True

is chained comparison, and is evaluated as:

x in range(2) and range(2) == True

which will give you False as range(2) == True is evaluated to False. See documentation for Comparison:

Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).

Upvotes: 4

Related Questions