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

Python列表追加字典时已存入数据被意外修改问题排查

问题根因

Python列表的append()方法存储的是对象的内存引用,不是对象的独立拷贝。
你在外层遍历时间戳的循环中,每个时间戳仅初始化了1次raw字典,内层5次循环全程都在修改这同一个字典对象。每次append操作只是把这个字典的内存地址存入列表,并没有生成新的字典。
你在append之后立刻打印data[-1]时值正常,是因为刚完成tag赋值,此时字典的tag值就是当前count;等下一次内层循环修改同一个raw的tag字段时,列表里之前存的所有指向该内存地址的条目,都会同步显示修改后的最新值,最终同时间戳的5条记录tag会全部等于该批次最后一次赋值的结果。

对应典型错误实现
import pandas as pd
from random import randrange, choice

# 菌种基础数据
cultures = [
    {"culture_name": "大肠杆菌", "scientific_name": "Escherichia coli"},
    {"culture_name": "枯草芽孢杆菌", "scientific_name": "Bacillus subtilis"},
    {"culture_name": "金黄色葡萄球菌", "scientific_name": "Staphylococcus aureus"}
]
times = pd.date_range(start="2024-01-01", periods=10, freq="D")
data = []
count = 0

for ts in times:
    # 问题点:每个时间戳只创建1个字典,内层循环全程复用
    raw = dict()
    selected_culture = choice(cultures)
    raw["culture_name"] = selected_culture["culture_name"]
    raw["scientific_name"] = selected_culture["scientific_name"]
    raw["generation"] = randrange(1, 30)
    raw["stage"] = randrange(1, 6)
    raw["user_id"] = 1
    raw["created_at"] = ts
    raw["updated_at"] = ts
    for _ in range(5):
        raw["tag"] = count
        count += 1
        data.append(raw)
        # 此时打印刚修改完的字典,值看似正确
        print("刚追加的条目:", data[-1])
修复方案

核心原则:每次append到列表的必须是独立的字典对象,不要跨循环复用同一个可变字典。
针对你的场景,最简便的写法是把固定字段先存为基础字典,内层循环每次生成基础字典的浅拷贝,再赋值独立的tag字段:

for ts in times:
    selected_culture = choice(cultures)
    # 先组装同时间戳下共有的固定字段
    base_data = {
        "culture_name": selected_culture["culture_name"],
        "scientific_name": selected_culture["scientific_name"],
        "generation": randrange(1, 30),
        "stage": randrange(1, 6),
        "user_id": 1,
        "created_at": ts,
        "updated_at": ts
    }
    for _ in range(5):
        # 每次循环生成独立副本,再赋值独有的tag字段
        raw = base_data.copy()
        raw["tag"] = count
        count += 1
        data.append(raw)

如果后续字典里存在嵌套的可变对象(比如值是列表、其他字典),把base_data.copy()换成copy.deepcopy(base_data)即可,当前场景全是一维不可变值,浅拷贝完全够用。
修复后再打印全量data列表,50条数据的tag会从0到49连续递增,不会再出现同批次tag重复的问题。

内容的提问来源于stack exchange,提问作者The Candy King

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:24:30