Hmm... An idea: if a,b==c,d:

Alex Martelli aleax at aleax.it
Tue Nov 19 08:05:34 EST 2002


Michael Hudson wrote:

> Alex Martelli <aleax at aleax.it> writes:
> 
>> Richard Dillingham wrote:
>> 
>> >> It's better written as:
>> >>
>> >> if coords[0]<=posx<=coords[2] and coords[1]<=posy<=coords[3]:
>> > 
>> > Hmm.... I just tried that, and am quite amazed to find that it actually
>> > works.
>> 
>> Python comparison operators CHAIN -- a wonderful little trait...
> 
> Indeed they do.  There's a wonderful little wart, though.  What does
> this:
> 
> if 1 in [1] < 2:
>   print 1
> else:
>   print 2
> 
> print?
> 
> Cheers,
> M.
> (actually, the answer may be Python version dependent...)

Order-comparisons between objects of different types are indeed
not guaranteed to work consistently except within one Python run,
I believe, so, yes, the [1]<2 part might return True (or equally
1) one day, False (or equally 0) the other.  the "1 in [1]" part
will of course always be True (1), so that has no influence in
determining the result of the "and" (chaining implies "and").

Whether it's a wart (big or little) that Python allows order
comparison between objects of almost-arbitrary types (so you
can check if a list is less than an int... but not if a list
is less than a complex!) -- I don't know: I'll give it a +0.
I have in the past relied on that to "sort" a heterogenous
list (being interested just in separating all strings from
all ints etc), and I suspect I'm not the only one to have done
similarly iffy things, so maybe we're stuck with that for
backwards compatibility anyway.

That Python lets you chain _arbitrary_ comparisons (including
order, equality, inequality, identity, membership) might also
arguably be considered a wart, but I would disagree on that
one.  The semantics of chaining are well defined: for any
comparison operators OP1, OP2, ... OPN,

  ob0 OP1 ob1 OP2 ... OPN obN

is exactly like

  (ob0 OP1 ob1) and (ob1 OP2 ... ) and (... OPN obN)

this can of course be used to construct unreadable expressions,
but so can just about anything else.  As I went on to state, I
would consider it very iffy style even to code just:

    if x < y >= z :

and would rather suggest stylistically constraining the OPj
sequence so that either all OPj are one of (< <= ==) or else
all of them are one of (> >= ==).  But I don't think it's
anything like a wart that Python doesn't force you to use
decent, readable style in this respect, any more that the fact
that Python can't (doesn't even try...) stop you from naming
all of your variables x0, x1, x2, x3, ... -- which is liable
to result in code at least as unreadable as funny chaining.


Alex




More information about the Python-list mailing list