[PEP202 listcomps] (was RE: [Python-Dev] Product iteration)

Peter Schneider-Kamp nowonder@pool.informatik.rwth-aachen.de
Wed, 26 Jul 2000 11:24:44 +0000


[Fredrik Lundh]
> 
> and personally, I prefer their "tuple former" syntax over the the
> current PEP202 proposal:
> 
>     [expression : iterator]
> 
>     [n : n in [1:100]]
>     [(x**2, x) : x in [1:5]]
>     [a : a in y if a > 5]

Funny. I send a mail to Tim this morning with a similar proposal:

[Peter]
> 
> Not being too happy with the proposed syntaxes I came up
> with a new one.
> 
> I think it is much better to parse (for human readers),
> but I am open about ';' as the delimiter. ':' would feel
> very fine to me, too.
> 
> Syntax:
> [<expr>; <cond>, <cond>, ...]
> 
> Example for semantics:
> [x+y; x in [1, 2, 3], x <= 2, y in [10, 20, 30], y in [5, 10, 20]]
> == [11, 21, 12, 22]
> 
> How to implement this example:
> (only a sketch, this will probably be too slow to
> really do it like this, but maybe you get the idea
> that it is at least possible to do it)
> 1) set baselist_for_x and baselist_for_y to
>    something special (None?) indicating all possible
>    values for x and y (they are unconstrained)
> 2) on encountering "x in [1, 2, 3]" set
>    baselist_for_x to [1, 2, 3]
> 3) on encountering "x <= 2" filter baselist_for_x
>    and get [1, 2]
> 4) on encountering "y in [10, 20, 30]" set
>    baselist_for_y to [10, 20, 30]
> 5) on encountering "y in [5, 10, 20] see that
>    baselist_for_y != special value (None?) and so
>    filter baselist_for_y and get [10, 20]
> 6) produce cross product of baselist_for_x
>    and baselist_for_y
> 7) apply expression to elements of cross product
> 
> The general idea is to start with lists of all
> possible values (represented by a special value)
> and use the conditions in the list comprehension
> to constrain that list. If we don't want to deal
> with infinite lists (and therefore lazy stuff)
> we could through an ConstraintError on the following:
> 
> >>> [x; x > 10000]
> ConstraintError: missing sequence constraint for x

The difference (besides ';' against ':') is the use of commas
for seperation and not using if.

[Fredrik Lundh]
> is there any special reason why we cannot use colon instead
> of "for"?

There seem to be some reasons, but I am not sure I have understood
them. Probably I'll best quote from Tim's reply:

[Tim Peters]
> That said, I can guarantee Guido will hate that in
> 
> > [x+y; x in [1, 2, 3], x <= 2, y in [10, 20, 30], y in [5, 10, 20]]
> 
> you have
>    y in [...]
> meaning iteration in one position but have it meaning a filter in another.

No. I have it mean filter in all cases. That's just implementation.

[Tim Peters]
> The syntax is also deadly ambiguous:
>    x <= 2
> is a legit Python expression today, but so is
>    x <= 2, y
> and so is
>    x <= 2, y in [10, 20, 30]
> and so is
>    x <= 2, y in [10, 20, 30], y
> etc.  This syntax is simply unparsable given the uses for commas in Python's
> existing expression syntax.  That's one reason "for" and "if" have been in
> every other proposal for at least the last year <wink>.

Wouldn't it be possible to just parse the first part (before the
delimiter - be it ';' or ':') as an expression and allow a tuple
of boolean expressions after the delimiter?

Picture list comprehensions as list constraints. With
  [x,y: x in list1, y in list2, x > 10, odd(y)]
I say that I want to have all tuples of x and y who
satisfy the following constraints:
- x is an element of list1 and greater than 10
- y is an element of list2 and odd

For the parser the following cases would both be valid:

[x+y: x in list1, y in list2]
[(x+y): (x in list1, y in list2)]

The latter would be what Python sees, but given that parentheses
are optional for expressions and tuple building the former would
be legal python.

[Tim Peters]
> Don't mean to be discouraging, but looks like you missed the first year of
> this debate!

Actually I think I did. But then I didn't even know about Python 4 months ago.

newbie-ly y'rs
Peter
--
Peter Schneider-Kamp          ++47-7388-7331
Herman Krags veg 51-11        mailto:peter@schneider-kamp.de
N-7050 Trondheim              http://schneider-kamp.de