You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python递归场景下yield是否会沿调用栈向上传递?

输出差异的核心原因

你观察到的交替输出本质是Python生成器的惰性求值特性导致的,和递归栈的展开逻辑无关,具体执行流程如下:

  • 当外层flatten遍历到元素[3,4,5]时,进入for subitem in flatten(item):循环,这里的flatten(item)会返回一个生成器对象,不会立刻执行内层函数的代码
  • 生成器每次迭代只会执行到下一个yield语句就暂停,返回当前值,下次迭代时从暂停位置继续执行,所以实际执行顺序是:
    1. 第一次迭代内层生成器:内层flatten处理元素3,匹配非列表分支,打印yield2 3,yield返回3,内层函数暂停
    2. 外层循环拿到subitem=3,执行print('yield1 ', 3),yield返回3
    3. 触发第二次迭代内层生成器:内层函数从暂停位置恢复,处理下一个元素4,匹配非列表分支,打印yield2 4,yield返回4,内层函数暂停
    4. 外层循环拿到subitem=4,执行print('yield1 ', 4),yield返回4
    5. 后续元素以此类推,就会出现yield2和yield1交替打印的结果
递归+yield的栈逻辑

递归场景下的yield完全遵循普通递归的栈规则,没有特殊的提前栈展开行为:每次内层函数yield返回值时,当前递归栈的所有状态都会被保存,直到下次迭代生成器时,再从当前暂停的栈位置继续执行。

符合你预期的修改方案

如果你想让内层生成器先执行完所有逻辑(打印所有yield2),再处理外层的打印逻辑,可以主动把内层生成器转为列表,强制它一次性执行完毕:

def flatten(lol):
    for item in lol:
        if isinstance(item, list):
            # 转list会一次性消耗内层生成器,打印所有内层yield2
            for subitem in list(flatten(item)):
                print('yield1 ', subitem)
                yield subitem
        else:
            print('yield2 ', item)
            yield item

内容的提问来源于stack exchange,提问作者dragor0123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 06:15:04