Python嵌套生成器不工作
我正在练习生成器,我想知道为什么下面的代码不打印16对,而只打印4对Python嵌套生成器不工作,python,generator,Python,Generator,我正在练习生成器,我想知道为什么下面的代码不打印16对,而只打印4对 def range_generator_function(my_range): for i in my_range: yield i gen1=range_generator_function(range(1,5)) gen2=range_generator_function(range(1,5)) def pairs_generator_function(gen1,gen2): for i
def range_generator_function(my_range):
for i in my_range:
yield i
gen1=range_generator_function(range(1,5))
gen2=range_generator_function(range(1,5))
def pairs_generator_function(gen1,gen2):
for it1 in gen1:
for it2 in gen2:
yield [it1,it2]
my_gen = pairs_generator_function(gen1,gen2)
for it in my_gen:
print(it)
输出是
[1, 1]
[1, 2]
[1, 3]
[1, 4]
而我期望的输出是
[1, 1]
[1, 2]
[1, 3]
[1, 4]
[2, 1]
[2, 2]
[2, 3]
[2, 4]
[3, 1]
[3, 2]
[3, 3]
[3, 4]
[4, 1]
[4, 2]
[4, 3]
[4, 4]
实际输出是正确的。您的
gen2
实例被第一个内部循环完全耗尽:
def pairs_generator_function(gen1,gen2):
for it1 in gen1:
for it2 in gen2: # <--- this consumes gen2
yield [it1,it2]
def对_生成器_函数(第1代、第2代):
对于gen1中的it1:
对于gen2中的it2:#您在第一次通过内部循环后耗尽了gen2。该流中不再有任何内容,因此it1
的其他三个值没有可配对的内容。您需要通过每次重新启动gen2
。考虑<代码>迭代器。TET<代码>克隆更多的副本。 < P>我修改了代码,这样我就得到了想要的输出,现在生成器每次在外环中重新创建。
def range_generator_function(my_range):
for i in my_range:
yield i
def pairs_generator_function():
gen1=range_generator_function(range(1,5))
for it1 in gen1:
gen2=range_generator_function(range(1,5))
for it2 in gen2:
yield [it1,it2]
my_gen = pairs_generator_function()
for it in my_gen:
print(it)
正如@wim所指出的,在第一次迭代之后,您的生成器已经完全耗尽了。但是,为了防止出现这种情况,将gen1
和gen2
作为列表传递给pairs\u generator\u function
。但是,您可以使用itertools.tee
存储原始生成器的两个副本:一个作为列表传递给函数,另一个供将来使用:
import itertools
def range_generator_function(my_range):
for i in my_range:
yield i
gen1=range_generator_function(range(1,5))
gen2=range_generator_function(range(1,5))
def pairs_generator_function(gen1,gen2):
for it1 in gen1:
for it2 in gen2:
yield [it1,it2]
gen1, gen1_l = itertools.tee(gen1)
gen2, gen2_l = itertools.tee(gen2)
print(list(pairs_generator_function(list(gen1_l), list(gen2_l))))
输出:
[[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4], [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]]
但是,请注意,gen1
和gen2`仍然指向内存中的项:
>>next(gen1)
1
>>next(gen2)
1
您得到的输出是由于在第二次迭代时,生成器gen2已耗尽
您可以在循环之前从中创建一个列表
,以存储其输出,也可以在每次迭代中使用itertools.tee
复制它。前者无法处理无限的生成器,但在实现后者之前,让我指出您实际上正在重新实现itertools.product
from itertools import product
my_gen = product(gen1, gen2)
for it in my_gen:
print(it)
我怎样才能使它再次可用?你不能。发电机是一次性的。您必须在第一次迭代期间保存这些值,或者创建一个新的生成器。相关:生成器是单遍迭代器。这非常有趣@Nisba我不确定是否有人展示了修复您的问题的代码,所以我将其添加到了我的答案中。我不认为这很复杂,但不得不额外使用gen1是一个小小的遗憾。但是,它确实使解决方案处于封装状态。