True == 1 weirdness

Chris Angelico rosuav at gmail.com
Wed Sep 16 16:26:16 CEST 2015


On Thu, Sep 17, 2015 at 12:03 AM, Random832 <random832 at fastmail.com> wrote:
> On Wed, Sep 16, 2015, at 09:05, Chris Angelico wrote:
>> My view is that they should remain in the language, but that
>> dissimilar comparisons should raise linter warnings. I can't imagine a
>> sane reason for chaining 'in' and equality like that (since the RHS of
>> 'in' will be a container, and if you're testing the whole container
>> for equality, you probably don't care about one member in it), but for
>> language consistency, it's good to support it.
>>
>> Chained comparisons of the same type are a great feature:
>
> Do chained "in" comparisons ever really make sense, even when they're
> all the same type?
>
> I mean, I suppose 1 in (1, 2) in ((1, 2), (3, 4)) is technically true,
> but how useful is it really?

Quite probably never. But are there _any_ comparison operators which
are unchainable? If not, there's no reason to disallow 'in'; this is
the distinction between language-level features and usage
recommendations. All comparisons can be chained, and the semantics of
(X op1 Y op2 Z) will always be ((X op1 Y) and (Y op2 Z)) but with Y
evaluated only once. That definition is fairly simple, and even though
it's a little wordy, it makes perfect sense; and the rule "all
comparisons" is way WAY simpler than "this specific set of chainable
operators", even if the only ones you'd ever actually want to chain
are the classic numeric operators (==, !=, <, >, <=, >=). According to
the operator precedence table [1], all comparison operators stand
together, and dividing that would mean making a once-for-everyone
decision about which are plausibly chainable. Remember, the language
rules can't know what kinds of objects we're working with; I can write
a __contains__ method that does whatever I want, but I can't decide
whether or not 'x in y in z' is evaluated as 'x in y and y in z', or
'(x in y) in z', or 'x in (y in z)', no matter what the types of x, y,
and z.

Far as I can see, the only operator that you might want to disallow
chaining on is 'in' (and its mate 'not in', of course). It isn't
common, but "x is y is z is None" is a perfectly reasonable way to
ascertain whether or not they're all None, just as "x = y = z = None"
is a perfectly reasonable way to set them all to None; the arguments
as to whether it should be "the wordy operators don't chain" or
"everything except 'in' chains" would be interminable. Much simpler to
stick with "all operators chain", which (conveniently) is status quo.
:)

ChrisA

[1] https://docs.python.org/3/reference/expressions.html#operator-precedence


More information about the Python-list mailing list