[Python-Dev] Tricky way of of creating a generator via a comprehension expression

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Thu Nov 23 01:12:46 EST 2017

Greg Ewing writes:

 > Consider this:
 >     def g():
 >        return ((yield i) for i in range(10))
 > Presumably the yield should turn g into a generator, but...
 > then what? My brain is hurting trying to figure out what
 > it should do.

I don't understand why you presume that.  The generator expression
doesn't do that anywhere else.  My model is that implicitly the
generator expression is creating a function that becomes a generator
factory, which is implicitly called to return the iterable generator
object, which contains the yield.  Because the call takes place
implicitly = at compile time, all the containing function "sees" is an
iterable (which happens to be a generator object).  "Look Ma, no
yields left!"  And then g returns the generator object.

What am I missing?

In other words, g above is equivalent to

    def g():
        def _g():
            for i in range(10):
                # the outer yield is the usual implicit yield from the
                # expansion of the generator expression, and the inner
                # yield is explicit in your code.
                yield (yield i)
        return _g()

(modulo some issues of leaking identifiers).  I have not figured out
why either your g or my g does what it does, but they do the same

More information about the Python-Dev mailing list