[Python-ideas] free variables in generator expressions

Brett Cannon brett at python.org
Wed Dec 12 21:56:25 CET 2007

On Dec 12, 2007 12:10 PM, Arnaud Delobelle <arno at marooned.org.uk> wrote:
> In the generator expression
>     (x+1 for x in L)
> the name 'L' is not local to the expression (as opposed to 'x'), I
> will call such a name a 'free name', as I am not aware of an existing
> terminology.
> The following is about how to treat 'free names' inside generator
> expressions.  I argue that these names should be bound to their values
> when the generator expression is created, and the rest of this email
> tries to provide arguments why this may be desirable.

Calling it a free variable is the right term (at least according to
Python and the functional programmers of the world).

As for what you are asking for, I do believe it came up during the
discussion of when genexps were added to the language.  I honestly
don't remember the reasoning as to why we didn't do it this way, but I
am willing to guess it has something to do with simplicity and purity
of what genexps are meant to be.

Consider what your genexp, ``(x for x in P if x % p)``, really is::

  def _genexp():
      for x in P:
        if x % p:
          yield x

But what you are after is::

  def _genexp():
    _P = P
    _p = p
    for x in _P:
      if x % _p:
        yield x

The former maps to what you see in the genexp much more literally than
the latter.  And if you want the latter, just define a function like
the above but have it take P and p as arguments and then you get your
generator just the way you want it.

Genexps (as with listcomps) are just really simple syntactic sugar.
And Python tends to skew from hiding details like capturing variables
implicitly in some piece of syntactic sugar.  In my opinion it is
better to be more explicit with what you want the generator to do and
just write out a generator function.


More information about the Python-ideas mailing list