Yielding from generator used inside another generator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | from collections import deque
class continuator:
def __init__(self, gen):
self.stack = deque([gen])
def __iter__(self):
return self
def next(self):
try:
gen = self.stack[-1]
except IndexError:
raise StopIteration
try:
ret_val = gen.next()
if hasattr(ret_val, 'gi_frame'):
self.stack.append(ret_val)
return self.next()
else:
return ret_val
except StopIteration:
try:
self.stack.pop()
return self.next()
except IndexError:
raise StopIteration
#### EXAMPLE ###########################################################
def gen_abcd():
for text in ['aaa','bbb','ccc','ddd']:
yield text
def gen_efgh():
for text in ['eee','fff','ggg','hhh']:
yield text
def gen_ijkl():
yield "iii"
yield gen_jk()
yield 'lll'
def gen_jk():
yield "jjj"
yield gen_k()
def gen_k():
yield "kkk"
def gen_all():
yield gen_abcd()
yield gen_efgh()
yield gen_ijkl()
for text in continuator(gen_all()):
print text
|
Tags: algorithms
Simplifying continuator code. This code shows more clearly what the continuator is doing:
Simpler still. Using a class seems overkill for this and gi_frame is most likely an implementation detail of generators. Also, why not make use of the wonderful itertools package: