# [Baypiggies] What is happening here with true/false comparisons

Damon McCormick damonmc at gmail.com
Tue Jan 26 00:03:30 CET 2010

While the suggested *fixes* are all correct (when in doubt, explicilty
parenthesize!), none of the *explanations* for the unexpected output are
quite right.  Since this involves a subtle issue, I thought I'd send a full
explanation.

It's tempting to assume that

>>> a in alist == b in alist
is equivalent to
>>> ((a in alist) == b) in alist

However, this is not correct!

For a simpler (but perhaps more confusing) example of the hazards of using
"in" and "==", non-parenthesized, in an expression like this, consider the
following:

>>> a = 1 # as before
>>> alist = [5,6] # as before
>>> a in alist == False
False
>>> (a in alist) == False
True

Weird, right?  And no, putting parens around (alist == False) won't
work--that would be an exception because the right side of the 'in' operator
wouldn't be iterable.

Here's one last example:

>>> blist = [1, [5,6]]
>>> 5 in alist == [5,6] in blist
True

You might enjoy the exercise of figuring out why the above output is
correct.  But to cut to the chase, what's going on is the following.  Python
allows comparisons to be chained, as in the following:

>>> a == 1 == 2/2
True
>>> 1 < 5 < 7
True

The way the chaining works (see 5.9 in http://tinyurl.com/3vsb6m) is that

>>> a == 1 == 2/2
is equivalent to
>>> (a == 1) and (1 == 2/2)

and

>>> 1 < 5 < 7
is equivalent to
>>> (1 < 5) and (5 < 7)

Since 'in' is just another comparison operator, it works the same way.
Thus, the the original expression

>>> a in alist == b in alist
is equivalent to
>>>(a in alist) and (alist == b) and (b in alist)

which is False because all three comparisons are False.  You'll see that the
two other examples I came up with make sense in this context as well.

-Damon

On Mon, Jan 25, 2010 at 1:27 PM, Asher Langton <langton2 at llnl.gov> wrote:

> On Jan 25, 2010, at 1:12 PM, Max Slimmer wrote:
>
>> Can anyone explain the following:
>>
>> >>> a = 1
>> >>> b = 2
>> >>> alist = [5,6]
>> >>> print a in alist
>> False
>>
>> >>> a in alist == b in alist
>> False
>> >>> a in alist == a in alist
>> False
>> >>> bool(a in alist) == bool(b in alist)      # this does what we expect
>> True
>> >>> c = 5
>> >>> c in alist == c in alist
>> False
>> >>>
>>
>
> The '==' and 'in' operators have the same precedence, so the expression 'a
> in alist == b in alist' is evaluated left-to-right as:
>
> >>> ( (a in alist) == b) in alist
>
> Since 'a in alist' is False, this is the same as
>
> >>> ( False == b) in alist
>
> which can be simplified to
>
> >>> False in alist
>
> which is False.
>
>
> -Asher
>
> _______________________________________________
> Baypiggies mailing list
> Baypiggies at python.org
> To change your subscription options or unsubscribe:
> http://mail.python.org/mailman/listinfo/baypiggies
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/baypiggies/attachments/20100125/770e088f/attachment.htm>