我有一个可能不是你想要的解决方案。它将n-元组生成器分离为n个单独生成器的元组。但是,它要求当前元组的每个单独值都已返回以继续下一个元组。严格地说,它将n-元组生成器“拆分”为n生成器,但是您的示例不能像前面介绍的那样工作。
它利用Python将值发送回生成器的能力来影响未来的产量。同样的想法也可以用类来实现,但是我还是想掌握生成器。在
当新的生成器被初始化时,它们只知道当前的n-元组。每次它们在各自的索引处生成值时,都会执行一个回调,通知更高级别的生成器该索引。一旦生成了当前元组的所有索引,更高级别的生成器将转到下一个元组并重复该过程。在
这可能有点笨拙,但下面是代码(Python3.6)。在from typing import TypeVar, Generator, Tuple, Iterator, Optional
TYPE_A = TypeVar("TYPE_A")
def _next_value(source: Iterator[Tuple[TYPE_A, ...]], size: int) -> Generator[Tuple[TYPE_A, ...], Optional[int], None]:
checked = [False for _ in range(size)]
value = next(source)
while True:
index = yield value
if all(checked):
value = next(source)
for _i in range(len(checked)):
checked[_i] = False
checked[index] = True
def _sub_iterator(index: int, callback: Generator[Tuple[TYPE_A, ...], int, None]) -> Generator[TYPE_A, None, None]:
while True:
value = callback.send(index)
yield value[index]
def split_iterator(source: Iterator[Tuple[TYPE_A, ...]], size: int) -> Tuple[Generator[TYPE_A, Optional[TYPE_A], None], ...]:
generators = []
_cb = _next_value(source, size)
_cb.send(None)
for _i in range(size):
each_generator = _sub_iterator(_i, _cb)
generators.append(each_generator)
return tuple(generators)
if __name__ == "__main__":
def triple():
_i = 0
while True:
yield tuple(range(_i, _i + 3))
_i += 1
g = triple()
for i, each_value in enumerate(g):
if i >= 5:
break
print(each_value)
print()
g = triple()
a_gen, b_gen, c_gen = split_iterator(g, 3)
for i, (a_value, b_value, c_value) in enumerate(zip(a_gen, b_gen, c_gen)):
if i >= 5:
break
print((a_value, b_value, c_value))
triple()是一个3元组生成器,split_iterator()生成三个生成器,每个生成器从{}生成的元组中生成一个索引。每个单独的_sub_iterator只在当前元组中的所有值都产生之后才继续。在