This question is asked out of purely curiosity/academic interest of Python as a language.
Suppose I have the following snippet:
>>> 1 in [1,2] == False
False
Which come out as expected as in takes precedence over == and 1 in [1,2] evaluates to True, and True != False.
But behold:
>>> 10 in [1,2] == False
False
Which is surprising because 10 in [1,2] evaluates to False and False == False should evaluates to True.
And I can prove that it is not because == is evaluated first, because it wouldn't even run:
>>> 10 in ([1,2] == False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'bool' is not iterable
While if in statement is run first by parenthesis it will return True:
>>> (10 in [1,2]) == False
True
# Note: All of above work in the same way if numbers and list are substituted by variables.
I went to dis and discovered an interesting caveat:
def func(): return (x in y == False)
dis.dis(func)
0 LOAD_FAST 0 (x)
2 LOAD_FAST 1 (y)
4 DUP_TOP
6 ROT_THREE
8 COMPARE_OP 6 (in)
10 JUMP_IF_FALSE_OR_POP 18
12 LOAD_CONST 1 (False)
14 COMPARE_OP 2 (==)
16 RETURN_VALUE
>> 18 ROT_TWO
20 POP_TOP
22 RETURN_VALUE
The JUMP_IF_FALSE_OR_POP bytecode entirely skips the == part (to 18) if FALSE. However, doing x in y == True also always evaluate to True on essentially the same bytecode. What's more, This bytecode is not seen in either in or == operations, something has to be generating it.
So what exactly is going on here? Why does everything in the format of x in y == (bool) Always evaluate to False? And what's actually happening behind the scene?