0

我有一项任务,我需要根据某些条件“切换”发电机中流的输出。

假设我们有一个生成器,它从某个无限来源产生数据。每次我们从生成器读取 1GB 数据时,我们都会将输出切换到其他读取器。

input = MyInfiniteGenerator()
Reader1(input) # does something with the first gigabyte of data
Reader2(input) # does something with the second gigabyte of data
...

当我们将输出从 Reader1 切换到 Reader2 时,Reader1 应该关闭。我无法改变读者的行为方式,他们只是迭代输入。

这个问题类似于旋转文件日志。

4

2 回答 2

1

我建议将您的生成器包装在另一个只会读取您想要的数量的生成器中。itertools.islice应该很好地完成工作:

import itertools

gen = someInfiniteGenerator()

while True:
    slice = itertools.islice(gen, 1000000) # reads one million items from gen
    reader = Reader(slice) # consumes all of the slice

唯一潜在的问题是,如果gen真的结束(即,它 raise StopIteration),你永远不会检测到它,除非 Reader 在它得到一个空的生成器时翻转。如果这是可能性,您可以使用额外级别的生成器来解决它,该生成器在生成任何内容之前检查生成器中是否至少有一个项目:

class EmptyGenerator(Exception):
    pass

def notEmptyGen(gen):
    try:
        first = next(gen)
        yield first
    except StopIteration: # empty source generator
        raise EmptyGenerator()

    yield from gen
于 2012-12-08T15:00:28.337 回答
0

你可以做类似的事情

input_chunk = (i for _, i in zip(xrange(chunk_size), input)) # `range` in Python3

或者,也许更一般地说,

from itertools import takewhile    
input_chunk = takewhile(condition, input)

并喂给等input_chunkReader1

condition必须是一个接受一个参数的函数—— 的项目input

另请注意,这input是一个内置函数的名称,并且将其用作变量名称会隐藏它。

上的文档itertools.takewhile

于 2012-12-08T14:20:13.987 回答