我有一个迭代器,例如:
from itertools import product
iterator_ = product([1, 2, 3], [7, 8, 9])
如果我尝试对迭代器进行多次迭代,那么我将无法执行,因为在完成第一次迭代后就用尽了。
如何从iterable_
生成可迭代的iterator_
,以便可以根据需要在迭代器上进行多次迭代?最好是一种有效的Python方式。
它不适用于所有迭代器-查看评论
到目前为止,我能够提出以下丑陋的解决方案:
from copy import copy
from typing import Iterable, Iterator
class WrappedIterator(Iterable):
"""
Wraps an iterator in an iterable
This allows to iterate over a given iterator more than once. Subsequent
actions on the given iterator do not have impact due to internal copying.
"""
def __init__(self, iterator: Iterator):
self._iterator = copy(iterator)
def __iter__(self) -> Iterator:
return copy(self._iterator)
def __next__(self):
raise NotImplementedError(
"One is not supposed to iterate over this object. Instead, "
"one should produce an iterator from it with `__iter__` and "
"iterate (as in, call `__next__` on the returned iterator).")
因此,以下内容使我可以从迭代器中创建一个可迭代的对象:
iterable_ = WrappedIterator(iterator_)
# The following does not fail
for _ in range(666):
assert len(list(iterable_)) > 0
# The following fails on attempt number 1
for i in range(666):
assert len(list(iterator_)) > 0, f"Failed on attempt {i}"
我在itertools.tee
或itertools.zip
上看到了一些帖子,但是我不确定这些解决方案是否足够高效且具有Python风格。但是我可以肯定他们是错的。