I have a list of generator functions like:
def myGen(x):
for i in range(x):
yield i
g5 = myGen(5); g10 = myGen(10); g15 = myGen(15)
cycleList = [g5, g10, g15]
What is the best way to cycle between these generators and remove the ones that are exhausted from the list?
The output should be:
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 6 6 7 7 8 8 9 9 10 11 12 13 14
It looks like you want the roundrobin
itertools
recipe:
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
In use:
>>> from itertools import cycle, islice
>>> for i in roundrobin(xrange(5), xrange(10), xrange(15)):
print i,
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 6 6 7 7 8 8 9 9 10 11 12 13 14
the round robin recipe is a better way to go but you could also use chain izip_longest and ifilterfalse:
from itertools import chain, izip_longest, ifilterfalse
for x in ifilterfalse(lambda x: x is None,chain.from_iterable(izip_longest(*cycleList))):
print x,
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 6 6 7 7 8 8 9 9 10 11 12 13 14
If you may have None as a value use object:
my_object = object
for x in ifilterfalse(lambda x: x is my_object,chain.from_iterable(izip_longest(*cycleList,fillvalue=my_object))):
print x,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With