📜 ⬆️ ⬇️

What does operation 1 <3 <2 return?

Answer: False

If we assume that this expression consists of two separate operations, then from left to right: 1 < 3 = True, True( 1) < 2 also return True , but for some reason False .

The trick is that 1 < 3 < 2 is not two separate operations, but one complex. Let's disassemble (into the pythonsea disassembler) our expression. As we see at the output, a very specific code:

 from dis import dis dis(lambda: 1<3<2) 1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (3) 6 DUP_TOP 7 ROT_THREE 8 COMPARE_OP 0 (<) 11 JUMP_IF_FALSE_OR_POP 21 14 LOAD_CONST 3 (2) 17 COMPARE_OP 0 (<) 20 RETURN_VALUE >> 21 ROT_TWO 22 POP_TOP 23 RETURN_VALUE 

')
Let us examine what is happening here. We load two constants into the stack and duplicate the last one for comparison later. Overturn the stack. We pull out 2 constants, compare. Putting the result on the stack. If Falls, then we leave. If Tru, then we get Tru from the stack. Load the third constant, and compare it with the second one, duplicated before. You can disassemble 1 <2 <3 <4 by yourself ... The code will be similar to the code above, only the corresponding blocks will be repeated. Still, it will be one complex operator.

But code 1<3 and 3<2 . It is very linear and clear:

 dis(lambda: 1<3 and 3<2) 1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (3) 6 COMPARE_OP 0 (<) 9 JUMP_IF_FALSE_OR_POP 21 12 LOAD_CONST 2 (3) 15 LOAD_CONST 3 (2) 18 COMPARE_OP 0 (<) >> 21 RETURN_VALUE 


Why such an operator is needed, because it is easier to write 1<3 and 3<2 . For example, I pars yaml:
 age: title: Age items: 1: up to 18 2: 18-25 3: above 25 


The following code:

 def range_age(age): for k, v in data['age'].items.items(): v = v.replace('up to','{}<') v = v.replace('above','{}>') v = v.replace('-','<={}<=') if eval(v.format(age)): return k 


Have a nice day, everyone!

PS Are there similar, complex operators in other languages?

Source: https://habr.com/ru/post/125671/


All Articles