在学习Bill Lubanovic介绍Python的过程中,我修改了一些代码以理解第9章中的flatte()函数
def flatten(lol):
for item in lol:
if isinstance(item, list):
for subitem in flatten(item):
print('yield1 ', subitem)
yield subitem
else:
print('yield2 ', item)
yield item
lol = [1, 2, [3, 4, 5], [6, [7, 8, 9],[]]]
list(flatten(lol))
我期望的输出是
('yield2 ', 1)
('yield2 ', 2)
('yield2 ', 3)
('yield2 ', 4)
('yield2 ', 5)
('yield1 ', 3)
('yield1 ', 4)
('yield1 ', 5)
...
...(skipped)
但程序的正确输出如下所示:
('yield2 ', 1)
('yield2 ', 2)
('yield2 ', 3)
('yield1 ', 3)
('yield2 ', 4)
('yield1 ', 4)
('yield2 ', 5)
('yield1 ', 5)
...
...(skipped)
我不明白为什么“('yield1',3)”在('yield2',4)之前被打印出来,即使调用的内部flatte()中的循环还没有结束。 我想知道递归时“yield”是否会展开堆栈
当您迭代
for subitem in flatten(item)
时,调用返回到flatten
,它首先打印项目yield2 value
,然后您在循环中使用yield1 value
再次打印它,这就是为什么,它会被打印两次,一次用于yield1,一次用于yield2,并且它不会像您在问题标题中提到的那样向上堆叠另一方面,建议使用
yield from ...
对生成器进行递归调用,而不是手动迭代生成器调用输出:
是的,
yield
语句暂停当前函数的执行,并将程序的控制权交给调用代码,其中生成的项将是正在迭代的生成器的下一个值。只有当从生成器请求进一步的值时,函数的内部调用才会恢复如果您尝试较小的输入,并尝试使用
next()
手动迭代,您可能会更好地理解:相关问题 更多 >
编程相关推荐