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

Python递归生成器使用list()或append()时失效问题求助

问题原因及解决方案

核心问题

你的递归生成器存在两个关键问题,导致转成列表时结果全部一致:

  1. 可变默认参数的陷阱:Python中,可变默认参数(如output={})会在函数定义阶段创建唯一的字典对象,所有递归调用共享这个字典,后续的修改都会覆盖之前的内容。
  2. yield引用而非副本:退出条件中yield output返回的是字典的引用,而非独立副本,所有生成器产出的元素都指向同一个字典实例。

直接遍历打印时看似正常,是因为每次打印操作发生在字典被修改之前,你看到的是当前时刻的字典状态;但转成列表时,所有元素的引用都指向同一个字典,最终字典被修改为最后一组参数,所以列表中所有元素都显示最后结果。

修复后的代码

修改默认参数初始化逻辑,并在yield时返回字典副本:

def _recursive_nWay_generator(input: list, output=None):
    '''
    Helper function; used to generate parameter-value pairs
    to submit to the model for the simulation.

    Parameters
    ----------
    input : list of tuple
        every tuple of the list must be of the form:
        ``('name_of_parameter', iterable_of_values)``

    output : dict, optional
        parameter used for recursion; allows for dict building
        across subgenerators

    Returns
    -------
    Generator :
        Specifications used for simulation setup of the form:
        ``{'par1': val1, ...}``
    '''
    # 初始化新字典,避免共享同一可变对象
    if output is None:
        output = {}
    # 退出条件:返回当前字典的副本,确保每个结果独立
    if len(input) == 0:
        yield output.copy()
    # 递归逻辑
    else:
        curr = input[0]
        par_name = curr[0]
        for par_value in curr[1]:
            output[par_name] = par_value
            yield from _recursive_nWay_generator(input[1:], output=output)

验证结果

运行测试代码:

testlist = [('a', (1, 2, 3)), ('b', (4, 5, 6)), ('c', (7, 8))]
gen = _recursive_nWay_generator(testlist)
print(list(gen))

会输出预期的所有参数组合,每个字典都是独立的实例,不会被后续修改覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:05:19