Why don't generators execute until first yield?

Ian Kelly ian.g.kelly at gmail.com
Wed May 7 05:17:35 EDT 2008


On Wed, May 7, 2008 at 2:29 AM, Martin Sand Christensen <msc at es.aau.dk> wrote:
>  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.

Isn't lazy evaluation sort of the whole point of replacing a list with
an iterator?  Besides which, running up to the first yield when
instantiated would make the generator's first iteration inconsistent
with the remaining iterations.  Consider this somewhat contrived
example:

def printing_iter(stuff):
    for item in stuff:
        print item
        yield item

Clearly, the idea here is to create a generator that wraps another
iterator and prints each item as it yields it.  But using your
suggestion, this would instead print the first item at the time the
generator is created, rather than when the first item is actually
iterated over.

If you really want a generator that behaves the way you describe, I
suggest doing something like this:

def myGenerator(args):
    immediate_setup_code()

    def generator():
        for item in actual_generator_loop():
            yield item
    return generator()



More information about the Python-list mailing list