[Python-Dev] Re: [Patches] [Patch #101175] Fix slight bug in the Ref manual docs on listcomprehensions

Tim Peters tim_one@email.msn.com
Wed, 16 Aug 2000 02:18:30 -0400


[Thomas Wouters]
> It'd be nice to hear *what* the exact syntax issue is. At first I thought
> you meant forcing parentheses around all forms of iterator
> expressions,

No, that's an old one, and was requiring parens around a target expression
iff it's a tuple.  So

    [x, y for x in s for y in t]  # BAD
    [(x, y) for x in s for y in t]  # good
    [(((x, y))) for x in s for y in t]  # good, though silly
    [x+y for x in s for y in t] # good
    [(x+y) for x in s for y in t] # good
    [x , for x in s] # BAD
    [(x ,) for x in s] # good

That much is already implemented in the patch currently on SourceForge.

> but apparently you mean requiring at least a single 'for' statement
> in a listcomp ?

No too <wink>, but closer:  it's that the leftmost ("first") clause must be
a "for".  So, yes, at least one for, but also that an "if" can't precede
*all* the "for"s:

   [x for x in s if x & 1] # good
   [x if x & 1 for x in s] # BAD
   [x for x in s]  # good
   [x if y & 1] # BAD

Since the leftmost clause can't refer to any bindings established "to its
right", an "if" as the leftmost clause can't act to filter the elements
generated by the iterators, and so Guido (me too) feels it's almost
certainly an error on the user's part if Python sees an "if" in the leftmost
position.  The current patch allows all of these, though.

In (mathematical) set-builder notation, you certainly see things like

    odds = {x | mod(x, 2) = 1}

That is, with "just a condition".  But in such cases the universe over which
x ranges is implicit from context (else the expression is not
well-defined!), and can always be made explicit; e.g., perhaps the above is
in a text where it's assumed everything is a natural number, and then it can
be made explicit via

    odds = {x in Natural | mod(x, 2) = 1|

In the concrete implementation afforded by listcomps, there is no notion of
an implicit universal set, so (as in SETL too, where this all came from
originally) explicit naming of the universe is required.

The way listcomps are implemented *can* make

   [x if y]

"mean something" (namely one of [x] or [], depending on y's value), but that
has nothing to do with its set-builder heritage.  Looks to me like the user
is just confused!  To Guido too.  Hence the desire not to allow this form at
all.