我有一个由多重yield返回的生成器对象。准备调用这个生成器是相当耗时的操作。这就是为什么我想重复使用发电机几次。
y = FunctionWithYield()
for x in y: print(x)
#here must be something to reset 'y'
for x in y: print(x)
当然,我正在考虑将内容复制到简单的列表中。有办法重置我的发电机吗?
请参见:如何提前查看Python生成器中的一个元素?
我有一个由多重yield返回的生成器对象。准备调用这个生成器是相当耗时的操作。这就是为什么我想重复使用发电机几次。
y = FunctionWithYield()
for x in y: print(x)
#here must be something to reset 'y'
for x in y: print(x)
当然,我正在考虑将内容复制到简单的列表中。有办法重置我的发电机吗?
请参见:如何提前查看Python生成器中的一个元素?
当前回答
如果GrzegorzOledzki的答案还不够,那么可以使用send()来实现目标。有关增强生成器和yield表达式的更多详细信息,请参阅PEP-0342。
更新:参见itertools.tee()。它涉及到上面提到的内存与处理之间的一些权衡,但它可能比仅将生成器结果存储在列表中节省一些内存;这取决于你如何使用发电机。
其他回答
你可以使用itertools.cycle()来实现这一点。 您可以使用此方法创建一个迭代器,然后在迭代器上执行for循环,迭代器将对其值进行循环。
例如:
def generator():
for j in cycle([i for i in range(5)]):
yield j
gen = generator()
for i in range(20):
print(next(gen))
将生成20个数字,0到4重复。
医生说:
Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).
现在可以使用more_itertools。Seekable(第三方工具),允许重置迭代器。
通过> pip Install more_itertools安装
import more_itertools as mit
y = mit.seekable(FunctionWithYield())
for x in y:
print(x)
y.seek(0) # reset iterator
for x in y:
print(x)
注意:内存消耗会随着迭代器的增加而增加,所以要警惕大型迭代对象。
这对我来说是工作。
csv_rows = my_generator()
for _ in range(10):
for row in csv_rows:
print(row)
csv_rows = my_generator()
如果GrzegorzOledzki的答案还不够,那么可以使用send()来实现目标。有关增强生成器和yield表达式的更多详细信息,请参阅PEP-0342。
更新:参见itertools.tee()。它涉及到上面提到的内存与处理之间的一些权衡,但它可能比仅将生成器结果存储在列表中节省一些内存;这取决于你如何使用发电机。
另一种选择是使用itertools.tee()函数创建生成器的第二个版本:
import itertools
y = FunctionWithYield()
y, y_backup = itertools.tee(y)
for x in y:
print(x)
for x in y_backup:
print(x)
从内存使用的角度来看,如果原始迭代可能不处理所有的项,这可能是有益的。