[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