[Python-Dev] namespace for generator expressions

Jeremy Hylton jeremy at alum.mit.edu
Mon Jan 26 19:51:34 EST 2004


On Mon, 2004-01-26 at 17:36, Phillip J. Eby wrote:
> The intent is that listcomps should be "safely" replaceable with genexprs 
> anywhere that an iterator is acceptable in place of a list.
> 
> >How often is a generator expression not going to be evaluated almost 
> >immediately? I guess, when they're passed to a function. But even in that 
> >case, how often are the bindings going to change? Except in pathological 
> >cases, they won't.
> 
> A trivial example is:

Are there non-trivial examples?  The PEP suggests that they exist, but
doesn't provide any.

> iterators = []
> for i in range(5):
>      iterators.append(x*2 for x in range(i))
> 
> print map(list,iterators)
> 
> If a listcomp is used, you get:
> 
> [[],[0,],[0,2],[0,2,4],[0,2,4,6],[0,2,4,6,8]]
> 
> If genexprs do late binding, you get:
> 
> [[0,2,4,6,8],[0,2,4,6,8],[0,2,4,6,8],[0,2,4,6,8],[0,2,4,6,8]]

Note that Armin Rigo suggested a small change here a few weeks ago that
makes the list comp and the gen expr behave the same way.  The range(i)
part of the gen expr is evaluated at the point of definition.  The gen
expr, thus, translates to:

def f(it):
    for x in it:
        yield x * 2

iterators.append(f(range(i))

As a result of this change, the only new scope is for the body of the
target expression.  I don't know how that effects the earlier examples.

BTW is there good terminology for describing the parts of a list comp or
gen expr?  How about the iterator, the conditions, and the expression?

Jeremy





More information about the Python-Dev mailing list