4

Going a bit mental here trying to work out what this does in python:

print "word" in [] == False

Why does this print False?

NullUserException
  • 83,810
  • 28
  • 209
  • 234
Tom Viner
  • 6,655
  • 7
  • 39
  • 40

3 Answers3

11

Perhaps a more clear example of this unusual behaviour is the following:

>>> print 'word' in ['word']
True
>>> print 'word' in ['word'] == True
False

Your example is equivalent to:

print ("word" in []) and ([] == False)

This is because two boolean expressions can be combined, with the intention of allowing this abbreviation:

a < x < b

for this longer but equivalent expression:

(a < x) and (x < b)
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 1
    is there any way to see how Python evaluates this internally? something like sql explain – Facundo Casco Sep 30 '11 at 22:48
  • 1
    @F.C.: You can do `import dis; dis.dis(lambda: 'word' in [] == False)` but it's quite tricky to read it. – Mark Byers Sep 30 '11 at 22:54
  • 1
    -1: "unexpected behaviour". It's far from unexpected. It's unusual because the construct is unusual. But it's far from unexpected. The expression rules are quite clear on this. Aren't they? http://docs.python.org/reference/expressions.html – S.Lott Sep 30 '11 at 23:58
3

Just like you can chain operators in 23 < x < 42, you can do that with in and ==.

"word" in [] is False and [] == False evaluates to False. Therefore, the whole result is

"word" in [] == False
"word" in [] and [] == False
False and False
False
phihag
  • 278,196
  • 72
  • 453
  • 469
1

Just to add to Mark Byers great answer

>>> import dis
>>> dis.dis(lambda: 'word' in [] == False)
  1           0 LOAD_CONST               1 ('word')
              3 BUILD_LIST               0
              6 DUP_TOP             
              7 ROT_THREE           
              8 COMPARE_OP               6 (in)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_GLOBAL              0 (False)
             17 COMPARE_OP               2 (==)
             20 RETURN_VALUE        
        >>   21 ROT_TWO             
             22 POP_TOP             
             23 RETURN_VALUE        
>>> dis.dis(lambda: ('word' in []) == False)
  1           0 LOAD_CONST               1 ('word')
              3 LOAD_CONST               2 (())
              6 COMPARE_OP               6 (in)
              9 LOAD_GLOBAL              0 (False)
             12 COMPARE_OP               2 (==)
             15 RETURN_VALUE        
Facundo Casco
  • 10,065
  • 8
  • 42
  • 63