Generator (re-)definition within a loop

Thomas Jollans thomas at jollans.com
Mon Jun 21 14:06:30 EDT 2010


On 06/21/2010 09:29 AM, Pierre Reinbold wrote:
> [snip]
> 
> Another try to avoid infinite recursion:
> 
> def badgen_product2(*args, **kwds):
>     pools = map(tuple, args)
>     result = [[]]
>     for pool in pools:
>         def augments():
>             for x in result:
This line is executed when you start iterating over the generator,
(because generators are lazy...). To get "result", which is not defined
in the inner function, Python looks in the namespace of the outer
function, where it's already been re-bound. So the generator basically
tries to iterate over itself (I think)

>                 for y in pool:
>                     yield x+[y]
>         result = augments()
>     for prod in result:
>         yield tuple(prod)
> 
> And this one gives the infamous:
> 
>     for x in result:
> ValueError: generator already executing
> 
> Which seems to indicate that the lazy evaluation leads to eventually
> bind everything to the same generator.
> 
> So, neither of my attempts reproduce the behaviour of the generator
> expression. What do I miss here ?

Bind "result" within the inner function. Either of these concepts should
work (not tested):

...
for pool in pools:
    def augments(result):
        for x in result:
            ...
    result = augments(result)
....

#or
...
result = lambda: [[]]
for pool in pools:
    def result(oldresult=result):
        for x in oldresult():
            ...

With the second option, Python takes "result" and saves it in the
definition of the new "result".


-- Thomas



More information about the Python-list mailing list