How does Python interpret "'a' in 'abc' is True"? I was trying to evaluate the following two expressions:
>>> 'a' in 'abc' is True:
False
>>> ('a' in 'abc') is True:
True
(I know "is" keyword shouldn't generally be used to compare to True
, this is just an example)
Interesting question!
Here's the bytecode from 'a' in 'abc' is True
:
>>> import dis
>>> dis.disassemble((lambda: 'a' in 'abc' is True).func_code)
2 0 LOAD_CONST 1 ('a') # stack: 'a'
3 LOAD_CONST 2 ('abc') # stack: 'a' 'abc'
6 DUP_TOP # stack: 'a' 'abc' 'abc'
7 ROT_THREE # stack: 'abc' 'a' 'abc'
8 COMPARE_OP 6 (in) # stack: 'abc' True
11 JUMP_IF_FALSE_OR_POP 21 # stack: 'abc'
14 LOAD_GLOBAL 0 (True) # stack: 'abc' True
17 COMPARE_OP 8 (is) # stack: False
20 RETURN_VALUE
>> 21 ROT_TWO
22 POP_TOP
23 RETURN_VALUE
And compare with that from ('a' in 'abc') is True
:
>>> import dis
>>> dis.disassemble((lambda: ('a' in 'abc') is True).func_code)
1 0 LOAD_CONST 1 ('a') # stack: 'a'
3 LOAD_CONST 2 ('abc') # stack: 'a' 'abc'
6 COMPARE_OP 6 (in) # stack: True
9 LOAD_GLOBAL 0 (True)
12 COMPARE_OP 8 (is)
15 RETURN_VALUE
So it seems like the expression 'a' in 'abc' is True
evaluates as roughly:
>>> 'a' in 'abc' and 'abc' is True
It seems like this is a result of operator chaining: https://stackoverflow.com/a/19751586/71522 — the same magic which makes 1 < 5 < 10
work properly.
Very interesting!
(Note: this was done with CPython 2.7.2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With