Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Result of "a is a is a" comparison [duplicate]

Tags:

python

A = 314

if A == A == A:
    print('True #1')

if A == A == 271:
    print('True #2')

lie = 0
if lie is lie is lie:
    print('no matter how white, how small,')
    print('how incorporating of a smidgeon')
    print('of truth there be in it.')

Result:

True #1
no matter how white, how small,
how incorporating of a smidgeon
of truth there be in it.

I know it is not normal to use two "="s and "is"s in the if sentence. But I would like to know how the Python interpreter intereprets the if statement.

Is the expression lie is lie is lie interpreted simultaneously, or short-circuit way?

like image 207
sevenOfNine Avatar asked Jan 18 '18 07:01

sevenOfNine


3 Answers

This question has many answers already, but consider the function split into bytecode:

def f():
    lie = 0
    if lie is lie is lie:
        print('Lie')

dis.dis(f)

  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               0 (lie)
  3           4 LOAD_FAST                0 (lie)
              6 LOAD_FAST                0 (lie)
              8 DUP_TOP
             10 ROT_THREE
             12 COMPARE_OP               8 (is)
             14 JUMP_IF_FALSE_OR_POP    22
             16 LOAD_FAST                0 (lie)
             18 COMPARE_OP               8 (is)
             20 JUMP_FORWARD             4 (to 26)
        >>   22 ROT_TWO
             24 POP_TOP
        >>   26 POP_JUMP_IF_FALSE       36
  4          28 LOAD_GLOBAL              0 (print)
             30 LOAD_CONST               2 ('Lie')
             32 CALL_FUNCTION            1
             34 POP_TOP
        >>   36 LOAD_CONST               0 (None)
             38 RETURN_VALUE

This suggests that all lies are being checked to see if they match, in a linear fashion. If one fails, it should break/return.

To confirm, consider:

>lie is lie is lie is lie is lie 
True
>lie is not lie is lie is lie is lie is lie
False
>lie is lie is lie is lie is lie is not lie
False
like image 168
Daniel Lee Avatar answered Nov 06 '22 16:11

Daniel Lee


It will be interpreted as:

lie = 0
if lie is lie and lie is lie:
    ...
like image 34
clemens Avatar answered Nov 06 '22 15:11

clemens


What you've happened across is called operator chaining.

From the documentation on Comparisons:

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).

Emphasis mine.

So, this would mean lie is lie is lie is interpreted as (lie is lie) and (lie is lie), and nothing more.

More generally, a op b op c op d ... is evaluated the same as a op b and b op c and c op d ... and so on. The expression is parsed according to python's grammar rules. In particular;

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"
like image 44
cs95 Avatar answered Nov 06 '22 16:11

cs95