如何将元组的Python生成器拆分为两个独立的生成器?
我有一个发电机,大致如下:如何将元组的Python生成器拆分为两个独立的生成器?,python,generator,Python,Generator,我有一个发电机,大致如下: def gen1(): for x, y in enumerate(xrange(20)): a = 5*x b = 10*y yield a, b for a in gen1_split_a(): yield a for b in gen1_split_b(): yield b 从这个生成器中,我想创建两个单独的生成器,如下所示: def gen1(): for x, y in e
def gen1():
for x, y in enumerate(xrange(20)):
a = 5*x
b = 10*y
yield a, b
for a in gen1_split_a():
yield a
for b in gen1_split_b():
yield b
从这个生成器中,我想创建两个单独的生成器,如下所示:
def gen1():
for x, y in enumerate(xrange(20)):
a = 5*x
b = 10*y
yield a, b
for a in gen1_split_a():
yield a
for b in gen1_split_b():
yield b
我的工作是什么,SA?你不能,除非你最终保持所有生成器输出,以便在第二个循环中生成
b
值。这在内存方面可能会很昂贵
您将使用“复制”生成器:
from itertools import tee
def split_gen(gen):
gen_a, gen_b = tee(gen, 2)
return (a for a, b in gen_a), (b for a, b in gen_b)
gen1_split_a, gen1_split_b = split_gen(gen1)
for a in gen1_split_a:
print a
for b in gen1_split_b:
print b
但是在这种情况下,tee
对象将不得不存储gen1
生成的所有内容。从文件中:
此itertool可能需要大量辅助存储(取决于需要存储的临时数据量)。通常,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,那么使用list()
而不是tee()
会更快
按照该建议,只需将b
值放入第二个循环的列表中:
b_values = []
for a, b in gen1():
print a
b_values.append(a)
for b in b_values:
print b
或者更好的方法是,在一个循环中同时处理
a
和b
。我有一个解决方案,可能不是您想要的。它将n
-元组生成器分离为n
单个生成器的元组但是,它要求返回当前元组的每个单独值以继续下一个元组。严格地说,它将一个n
-元组生成器“拆分”为n
生成器,但您的示例不会像前面介绍的那样工作。
它利用Python将值发送回生成器以影响未来收益率的能力。同样的想法也应该可以用类来实现,但我还是想掌握生成器
初始化新生成器时,它们只知道当前的n
-元组。每次它们在各自的索引中生成值时,都会执行回调,将此索引通知给更高级别的生成器。一旦生成了当前元组的所有索引,更高级别的生成器将移动到下一个元组并重复该过程
这可能有点笨拙,但下面是代码(Python3.6)
triple()
是一个三元组生成器,split_iterator()
生成三个生成器,每个生成器从triple()
生成的元组中生成一个索引。每个\u sub\u迭代器
仅在当前元组中的所有值都已生成后才能进行处理。您可以在gen1()中对a,b执行:
,但如果您需要所有a
,则所有b
我建议进行完整的重组;使用生成器没有任何意义,因为您需要预先获得所有对。您只需运行生成器两次,每次只使用两个元素中的一个。为什么不直接执行gen=gen1()
和def gen_bs(gen):对于gen中的b:产生b[1]
?,然后gen_bs(gen)
?谢谢Martijn!前者成功了。也就是说,我做了一些重构,并从代码中完全忽略了这一点。不过,我还是把它保存在我的笔记里,以备下次使用!