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

Ryan Delucchi bender at onsrc.com
Tue Jan 26 00:25:19 CET 2010


huh, I knew about chaining in Python but didn't realize that "in" also  
exhibits this behavior.

Now, as much as I like many of the neat features in Python (including  
logic chaining), I am going to go out on a limb
and say that this is a particularly confusing use of chaining and  
should be avoided (for the same reason that
folks programming in C should make judicious use of pointer arithmetic).

But pragmatics aside, this is actually pretty cool and good to know.

Ryan

On Jan 25, 2010, at 3:03 PM, Damon McCormick wrote:

> 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
>
> _______________________________________________
> 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/809fc1de/attachment-0001.htm>


More information about the Baypiggies mailing list