Reputation: 21
Let's say we have
a = [1, 2]
Then in the interpreter,
for e in a: print e in a
prints
True
True
BUT the following code doesn't make sense to me or any of my python-expert friends
for e in a: print e in a == True
prints
False
False
Can someone explain this?
Upvotes: 1
Views: 32
Reputation: 249462
If we boil the confusing expression down, it is:
1 in a == True
This gives False
(we might have expected True
). So let's use the ast
module to inspect it:
>>> import ast
>>> print ast.dump(ast.parse('1 in a == True'))
Module(body=[
Expr(value=Compare(
left=Num(n=1),
ops=[In(), Eq()],
comparators=[
Name(id='a', ctx=Load()),
Name(id='True', ctx=Load())
]))
])
Compare with a version with added parentheses which works the way you'd probably expect:
>>> print ast.dump(ast.parse('(1 in a) == True'))
Module(body=[
Expr(value=Compare(
left=Compare(
left=Num(n=1),
ops=[In()],
comparators=[
Name(id='a', ctx=Load())
]),
ops=[Eq()],
comparators=[
Name(id='True', ctx=Load())
]))
])
Do you see the difference? The second one is like Eq(In(1, a), True)
as we'd expect. But the first is In(1, a) Eq(a, True)
. What? How do those two things go together? Well, they form a conjunction, like and
.
So it ends up that the first expression is equivalent to 1 in a and a == True
.
But why?
It's because Python supports "chained conditionals," like this:
1 < 3 < 5
Your example is just collateral damage: apparently not only are conditionals like <
chained, but in
counts too. This isn't intuitive to me, but that's how it works. You can read more about chaining here: https://docs.python.org/2/reference/expressions.html#not-in
Upvotes: 1