Why don't generators execute until first yield?

Diez B. Roggisch deets at nospam.web.de
Wed May 7 11:25:03 EDT 2008


> Now to the main point. When a generator function is run, it immediately
> returns a generator, and it does not run any code inside the generator.
> Not until generator.next() is called is any code inside the generator
> executed, giving it traditional lazy evaluation semantics. Why don't
> generators follow the usual eager evaluation semantics of Python and
> immediately execute up until right before the first yield instead?
> Giving generators special case semantics for no good reason is a really
> bad idea, so I'm very curious if there is a good reason for it being
> this way. With the current semantics it means that errors can pop up at
> unexpected times rather than the code failing fast.

The semantics of a generator are very clear: on .next(), run until the next
yield is reached and then return the yielded value. Plus of course the
dealing with StopIteration-stuff.

Your scenario would introduce a special-case for the first run, making it
necessary to keep additional state around (possibly introducing GC-issues
on the way), just for the sake of it. And violate the lazyness a generator
is all about. Think of a situation like this:

def g():
    while True:
       yield time.time()

Obviously you want to yield the time at the moment of .next() being called.
Not something stored from ages ago. If anything that setups the generator
shall be done immediatly, it's easy enough:

def g():
   first_result = time.time()
   def _g():
      yield first_result
      while True:
         yield time.time()
   return _()

Diez



More information about the Python-list mailing list