我有一个生成器函数列表,如:
def myGen(x):
for i in range(x):
yield i
g5 = myGen(5); g10 = myGen(10); g15 = myGen(15)
cycleList = [g5, g10, g15]
在这些生成器之间循环并从列表中删除耗尽的生成器的最佳方法是什么?
输出应为:
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
答案 0 :(得分:4)
看起来你想要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))
使用中:
>>> 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
答案 1 :(得分:2)
循环法食谱是一种更好的方法,但你也可以使用chain izip_longest和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
如果您可以将None作为值使用对象:
my_object = object
for x in ifilterfalse(lambda x: x is my_object,chain.from_iterable(izip_longest(*cycleList,fillvalue=my_object))):
print x,