列表推导式有副作用吗?Python树前序递归实现问题咨询
为什么利用生成器表达式的副作用无法实现树的前序递归遍历?
核心原因是生成器表达式的惰性求值特性:你定义的a = (ret.extend(preorder(b)) for b in branches(t))是一个生成器对象,它内部的代码不会立即执行,只有当主动迭代这个生成器时(比如用for循环遍历、转成列表list(a)等),才会逐步执行其中的语句。
看你的有效代码:
def preorder(t): ret = [label(t)] for branch in branches(t): ret.extend(preorder(branch)) return ret
这里的for循环会主动遍历branches(t)的每一个元素,每次循环都执行ret.extend(preorder(branch))——既完成了递归遍历子树,又把结果扩展到ret里,所有操作都是即时执行的。
而无效代码里,你只是把生成器赋值给了变量a,之后完全没有对a做任何迭代操作,所以生成器内部的ret.extend(preorder(b))一行都没有被执行,ret自然只保留了初始的[label(t)],也就是[1]。
如果非要用类似的写法(非常不推荐,依赖副作用的代码可读性差、维护成本高),你可以强制迭代生成器触发执行,比如把生成器转成列表:
def preorder(t): ret = [label(t)] # 强制迭代生成器,触发里面的extend操作 list(ret.extend(preorder(b)) for b in branches(t)) return ret
但这种写法完全没有必要,原有的for循环逻辑清晰、易于理解,是更优的实现方式。
内容的提问来源于stack exchange,提问作者Callum Ethan
相关产品推荐
相关产品推荐

