返回信息流最近在看《Python基础教程》自学中。
目前看到9.7.2节“递归生成器”。
其中有个例子是把多层嵌套的列表展开
书上的例子是:
def flatten( nested ):
try:
for sublist in nested:
for element in flatten( sublist ):
yield element
except TypeError:
yield nested
n = [ [ [ 1 ], 2 ], 3, 4, [ 5, [ 6, 7 ], 8 ] ]
list( flatten( n ) )
[1,2,3,4,5,6,7,8]
我想改写成这样:
def flatten( nested ):
try:
for element in nested:
flatten( element )
except TypeError:
#print( nested )
yield nested
n = [ [ [ 1 ], 2 ], 3, 4, [ 5, [ 6, 7 ], 8 ] ]
list( flatten( n ) )
[]
但完全不成功,输出是个空列表.
但是如果我不写成生成器,而是用print语句,能够递归地正确打印出来。
我的理解是用了yield语句,执行到yield就停住了。
所以递归实现的print都是正确的,那yield也应该是正确的
不知道哪点理解得不对,或者别的什么书上有不同的讲解?
这是一条镜像帖。来源:北邮人论坛 / python / #22321同步于 2018/7/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
新手求教递归生成器
dzcs
2018/7/12镜像同步6 回复
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
例子里元素1发生error以迭代器形式返回,因为是个迭代器,所以可以正常yield element。你的代码里当1发生错误返回后,外层的函数没有继续把1 yield出去,自然就没输出了
楼上正解 显然当e抛出时 你没有yield 你试着改为yield element试试 而且就算可以的话 也没有上面的代码效率高 你的多迭代了一层
yield相当于可以部分理解为return。书上代码yield都能返回到最外层的函数。你的代码yield只返回到了内层函数,用生成器无法捕捉到。换句话说,flatten()这个生成器只能生成自己yield的结果,生成器的内层函数yield再多,都没用。但是print不同,不管你在哪个函数,第几层,只要print了,就能在屏幕显示。
【 在 dzcs (【魔都适应纪】山坡林) 的大作中提到: 】
: 最近在看《Python基础教程》自学中。
: 目前看到9.7.2节“递归生成器”。
: 其中有个例子是把多层嵌套的列表展开
: ...................
楼上的基本把原因说清楚了,所以书上的例子的写法其实是必要的,实在要改的话需要用到yield from语法, 需要改成``yield from flatten(element)``
谢
大概理解了:
也就是说并不是遇到yield,整个代码在执行中就停顿下来了?
而是最外层的yield才能使得执行着的代码停下来?
并且也只有最外层的yield才能产出生结果?
所以说书上的代码用了
for element in flatten( sublist ):
yield element
用for把内层生成器的产出的结果在本层收到element中,再重新yield产出到上层?
应该这么理解吧?
也所以说,我原先的代码,在最外层只有except下才有yield
所以我的代码只有
list( flatten( 1 ) )
[1]
这一种情况下才正常
【 在 Nessaj 的大作中提到: 】
: yield相当于可以部分理解为return。书上代码yield都能返回到最外层的函数。你的代码yield只返回到了内层函数,用生成器无法捕捉到。换句话说,flatten()这个生成器只能生成自己yield的结果,生成器的内层函数yield再多,都没用。但是print不同,不管你在哪个函数,第几层,只要print了,就能在屏幕显示。