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