Question or problem about Python programming:
If I do this:
>>> False in [False, True] True
That returns True. Simply because False is in the list.
But if I do:
>>> not(True) in [False, True] False
That returns False. Whereas not(True) is equal to False:
>>> not(True) False
Why?
How to solve the problem:
Solution 1:
Operator precedence 2.x, 3.x. The precedence of not
is lower than that of in
. So it is equivalent to:
>>> not ((True) in [False, True]) False
This is what you want:
>>> (not True) in [False, True] True
As @Ben points out: It’s recommended to never write not(True)
, prefer not True
. The former makes it look like a function call, while not
is an operator, not a function.
Solution 2:
not x in y
is evaluated as x not in y
You can see exactly what’s happening by disassembling the code. The first case works as you expect:
>>> x = lambda: False in [False, True] >>> dis.dis(x) 1 0 LOAD_GLOBAL 0 (False) 3 LOAD_GLOBAL 0 (False) 6 LOAD_GLOBAL 1 (True) 9 BUILD_LIST 2 12 COMPARE_OP 6 (in) 15 RETURN_VALUE
The second case, evaluates to True not in [False, True]
, which is False
clearly:
>>> x = lambda: not(True) in [False, True] >>> dis.dis(x) 1 0 LOAD_GLOBAL 0 (True) 3 LOAD_GLOBAL 1 (False) 6 LOAD_GLOBAL 0 (True) 9 BUILD_LIST 2 12 COMPARE_OP 7 (not in) 15 RETURN_VALUE >>>
What you wanted to express instead was (not(True)) in [False, True]
, which as expected is True
, and you can see why:
>>> x = lambda: (not(True)) in [False, True] >>> dis.dis(x) 1 0 LOAD_GLOBAL 0 (True) 3 UNARY_NOT 4 LOAD_GLOBAL 1 (False) 7 LOAD_GLOBAL 0 (True) 10 BUILD_LIST 2 13 COMPARE_OP 6 (in) 16 RETURN_VALUE
Solution 3:
Operator precedence. in
binds more tightly than not
, so your expression is equivalent to not((True) in [False, True])
.
Solution 4:
It’s all about operator precedence (in
is stronger than not
). But it can be easily corrected by adding parentheses at the right place:
(not(True)) in [False, True] # prints true
writing:
not(True) in [False, True]
is the same like:
not((True) in [False, True])
which looks if True
is in the list and returns the “not” of the result.
Solution 5:
It is evaluating as not True in [False, True]
, which returns False
because True
is in [False, True]
If you try
>>>(not(True)) in [False, True] True
You get the expected result.