Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python嵌套生成器不工作_Python_Generator - Fatal编程技术网

Python嵌套生成器不工作

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

我正在练习生成器,我想知道为什么下面的代码不打印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 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是一个小小的遗憾。但是,它确实使解决方案处于封装状态。