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

Python循环中字典列表输出异常原因解析

问题原因分析:字典引用导致的列表元素异常修改

问题场景

你期望生成包含所有参数组合的字典列表,正确输出应该是:

[  
{'l1': 0, 'lp1': 0},   
{'l1': 0, 'lp1': 1},   
{'l1': 1, 'lp1': 0},   
{'l1': 1, 'lp1': 1}
]

但运行提供的代码后,最终得到的却是所有lp1值都为1的列表:

[  
{'l1': 0, 'lp1': 1},   
{'l1': 0, 'lp1': 1},  
{'l1': 1, 'lp1': 1},  
{'l1': 1, 'lp1': 1}
]

且迭代过程中打印的临时结果是正确的,但后续迭代会修改已添加到列表中的元素。

你的代码如下:

from itertools import product
from typing import Iterable, Any

l_params = {
    "l1": [0,1]
}

lp_params = {
    "lp1": [0,1]
}

def grid_parameters(parameters: dict[str, Iterable[Any]]) -> Iterable[dict[str, Any]]:
    for params in product(*parameters.values()):
        yield dict(zip(parameters.keys(), params))

outlist = []

for l_settings in grid_parameters(l_params):
    for lp_settings in grid_parameters(lp_params):
        settings = l_settings
        settings['lp1'] = lp_settings['lp1']
        outlist.append(settings)
        print('ls', outlist)

核心原因:字典是可变对象,列表存储的是引用

Python中,字典属于可变对象,当你执行settings = l_settings时,并没有创建新的字典,而是让settings指向了和l_settings完全相同的内存地址。

每次循环的具体逻辑:

  • 第一次内层循环:给这个共享的字典添加lp1:0,并把字典的引用加入列表;
  • 第二次内层循环:修改同一个字典的lp1值为1,此时列表中之前添加的引用指向的还是这个字典,所以已存在的元素也会跟着变成lp1:1;
  • 外层循环切换到l1:1的字典时,重复上述逻辑,最终列表里的所有元素都指向两个原始字典(l1:0和l1:1),而这两个字典的lp1最后都被修改为1,所以最终输出全是lp1:1。

你用字符串解决问题,是因为字符串是不可变对象,每次转换都会生成新的字符串实例,列表里存储的是不同的字符串,不会被后续修改影响。

解决办法:创建字典的副本

要避免这个问题,每次循环时需要创建字典的新副本,而不是直接引用原字典。常用两种方式:

  1. 使用字典的copy()方法:
for l_settings in grid_parameters(l_params):
    for lp_settings in grid_parameters(lp_params):
        settings = l_settings.copy()  # 创建原字典的副本
        settings['lp1'] = lp_settings['lp1']
        outlist.append(settings)
  1. 使用字典解包生成新字典:
for l_settings in grid_parameters(l_params):
    for lp_settings in grid_parameters(lp_params):
        settings = {**l_settings, **lp_settings}  # 合并两个字典生成新实例
        outlist.append(settings)

这样每次添加到列表的都是独立的字典实例,后续修改不会影响已添加的元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:40:27