tags:

views:

94

answers:

1

Here's the code, I don't quite understand, how does it work. Could anyone tell, is that an expected behavior?

$ipython

In [1]: 1 in [1] == True
Out[1]: False

In [2]: (1 in [1]) == True
Out[2]: True

In [3]: 1 in ([1] == True)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/dmedvinsky/projects/condo/condo/<ipython console> in <module>()

TypeError: argument of type 'bool' is not iterable

In [4]: from sys import version_info

In [5]: version_info
Out[5]: (2, 6, 4, 'final', 0)
+11  A: 

This is an example of "chaining" which is a gotcha in Python. It's a (possibly silly) trick of Python that:

a op b op c

is equivalent to:

(a op b) and (b op c)

for all operators of the same precedence. Unfortunately, in and == have the same precedence, as do is and all comparisons.

So, here is your unexpected case:

1 in [1] == True  # -> (1 in [1]) and ([1] == True) -> True and False -> False

See See http://docs.python.org/reference/expressions.html#summary for the precedence table.

Charles Merriam
Chaining is often used for expressions like `1 < x < 5` (so it's not always silly), but in that case I was quite surprised too. Good exploration Charles!
tux21b
True, though I wish `1 < 5 > 2 < 3 in range(4) == [0, 1, 2, 3]` did not chain.
Charles Merriam
Thank you for good explanation.
d.m
Chaining is good, not a gotcha. Relying on guessed or incorrectly deduced operator precedence is bad in any language -- if it's anything out of the ordinary * + and or etc bracket, use parentheses!
John Machin
No. If anything is out of the ordinary such that it is likely an error would likely occur, the language should optimize programmer time and flag it.
Charles Merriam