[Python-Dev] For/while/if statements/comprehension/generator expressions unification

Josiah Carlson jcarlson at uci.edu
Tue Sep 20 19:20:44 CEST 2005


Alexander Myodov <maa_public at sinn.ru> wrote:
> Hello Josiah,
> 
> JC> Alexander,
> JC> The essence of what you have proposed has been proposed (multiple times) before,
> JC> and I seem to remember it was shot down.
> 
> To increase my understanding of Python-way, can you (or someone else)
> explain the reasons why such proposals were rejected?
> 
> JC> The below functions offer the equivalent of list comprehensions with a
> JC> final post-processing step.
> 
> Well, what I was suggesting is not just a cross of two lists but the
> syntax sugar which would make statements more consistent to the
> generators/comprehensions and also give some new opportunities.
> I think that my large proposal can be splitted to several
> almost-independent ones, each carrying separate features, able to
> be implemented independently and worth independent reconsidering:

Try using the code I offered.  It allows the cross of an aribitrary
number of restartable iterables, in the same order as an equivalent list
comprehension or generator expression.

>>> list(cross([1,2], [3,4], [5,6]))
[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4,
5), (2, 4, 6)]

There were a few hoops I had to jump through in cross in order to be
able to hande single iterables as well as tuples embedded in the passed
iterables, but they work as they should.

>>> list(cross([(1,1),(2,2)], [(3,3),(4,4)], [(5,5),(6,6)]))
[((1, 1), (3, 3), (5, 5)), ((1, 1), (3, 3), (6, 6)), ((1, 1), (4, 4), (5,
5)), ((1, 1), (4, 4), (6, 6)), ((2, 2), (3, 3), (5, 5)), ((2, 2), (3, 3),
(6, 6)), ((2, 2), (4, 4), (5, 5)), ((2, 2), (4, 4), (6, 6))]


> 1. Bring 'if'-s from generator/comprehension 'for' syntax to 'for'
> statement. That's truly inconsistent that one may write
> 
>  list2 = [i for i in list if cond(i)]
> 
> but cannot write
> 
>  for i in list if cond(i):

Note: list comprehensions and generator expressions have not been in
Python since the beginning.

List comprehensions were added in Python 2.0 as syntactic sugar for the
common case of list construction with simple predicates.

x = []
for i in y:
    for j in z:
        if f(i,j):
            x.append((i,j))

x = [(i,j) for i in y for j in z if f(i,j)]


If you are good, you can add predicates anywhere you want inside of for
loops using ifilter.

def f(i): return i%2==0
def g(i): return i**2%3 < 2

for i in ifilter(f, x):
    for j in ifilter(g, y):
        ...

No need to have syntax for something that is simple enough to use...

If you want to filter on multiple items (updated in each loop), there is
always the curry decorator and/or class offered in PEP 309 (minor
modification would offer a rightcurry).


For all of the reasons you offer, Nick has a great point that there is
no need to complicate the for loop with generator/list comprehension
semantics when you can embed either of them in the right side of the for
loop.

 - Josiah



More information about the Python-Dev mailing list