Sending changed parameters into nested generators

Arnaud Delobelle arnodel at gmail.com
Fri Nov 12 13:09:21 EST 2010


"John O'Hagan" <research at johnohagan.com> writes:

> I have a generator function which takes as arguments another generator and a 
> dictionary of other generators like this:
>
> def modgen(gen, gendict):
>     for item in gen():
> 	for k, v in gendict:
> 		do_something_called_k(item, v.next())
> 	yield item
>
> I want to control the output of this generator by sending in new values to the 
> generators in gendict. I have done this using a list in a simple generator 
> like: 
>
> def loop(lis):
>     while True:
> 	for item in lis:
>         	yield item
>
> and write:
>
> lis[:] = [new_value]
>
> to see the output of modgen() change.
>
> However, I want to be able to use other modgen() instances as values in 
> gendict, each with a gendict of its own, which in turn may contain modgen() 
> instances, and so on recursively. The recursion stops wherever a simple 
> generator like loop() is encountered.
>
> To this end I've made nested dictionaries like this example:
>
> {'a':[1,2,3], 'b':{'a':[4,5,6]}, 'c':{'a':{'a':[7,8,9], 'b':{'c':[10]}}}}
>  
> and used a recursive function to convert them to the gendict I'm after like 
> this:
>
> def iterized(dic):
>     itdic = {}
>     for k, v in dic.items():
>         if isinstance(v, dict):
>             itval = iterized(v)
>             itdic[k] = maingen(itval)
>         else:
>             itdic[k] = loop(v)
>     return itdic
>
> Then I can write:
>
> recdic = {nested:dictionary}
> gendict = iterized(recdict)
> mygen = modgen(gen, gendict)
>
> The problem is that the gendict looks like this:
>
> {'a': <generator object loop at 0x8841414>, 'b': <generator object modgen at 
> 0x8841464>, 'c': <generator object modgen at 0x884148c>}
>
> so I have no direct access from there to the sub-generators. 
>
> I have tried using a deep update function on the original nested dictionary, 
> but this only works if I  change the contents of a list, not if I want to, 
> say, change a node from a list to a dictionary or vice versa, because in that 
> case I'm not operating on the same object the generator is using.
>
> If anyone's still reading :) , how can I send new values to arbitrary sub-
> generators?
>
> Thanks,
>
> john

Try instead:

def loop(d, k):
    while True:
        for x in d[k]:
            yield x

def iterized(dic):
    itdic = {}
    for k, v in dic.items():
        if isinstance(v, dict):
            itval = iterized(v)
            itdic[k] = maingen(itval)
        else:
            itdic[k] = loop(dic, k)
    return itdic

Untested.

-- 
Arnaud



More information about the Python-list mailing list