以循环方式排出发电机列表

时间:2014-11-21 11:14:05

标签: python itertools

我有一个生成器函数列表,如:

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

2 个答案:

答案 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_longestifilterfalse

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,