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

Python循环中字典存列表重复引用,如何按值传递可变对象?

解决Python中字典可变对象的列表引用问题

这个坑我当初刚学Python的时候也踩过!因为字典是可变对象,你每次往列表里append的其实是它的引用,而不是当前状态的副本,所以最后列表里全指向同一个字典,自然都是最终状态。不过要实现你说的“保存每个迭代的状态快照”,方法有好几种,给你详细说下:


方法1:用字典的copy()方法做浅拷贝

这是最简单的方式,适合字典里没有嵌套可变对象(比如子字典、列表)的情况:

state = {"count": 0}
state_list = []

for i in range(3):
    state["count"] += 1
    # 追加当前字典的副本,而不是原字典的引用
    state_list.append(state.copy())

print(state_list)  # 输出:[{'count': 1}, {'count': 2}, {'count': 3}]

copy()会创建一个新的字典对象,和原字典内容相同,但彼此独立,后续修改原字典不会影响列表里的副本。

方法2:用copy.deepcopy()处理嵌套结构

如果你的state里有嵌套的可变对象(比如字典套列表、子字典),浅拷贝就不够用了——因为浅拷贝只会复制顶层引用,嵌套的可变对象还是共享的。这时候就得用copy模块的deepcopy():

import copy

state = {"count": 0, "nested_data": [1]}
state_list = []

for i in range(3):
    state["count"] += 1
    state["nested_data"].append(i + 2)
    # 深度复制,把所有嵌套的可变对象也都复制一遍
    state_list.append(copy.deepcopy(state))

print(state_list)
# 输出的每个元素都是完全独立的,嵌套列表不会跟着原字典变化

方法3:每次循环新建字典

干脆别在原字典上修改,每次迭代都创建一个全新的字典,从根源上避免引用共享问题:

state_list = []

for i in range(3):
    # 每次循环都生成新的字典,不存在引用复用
    current_state = {"count": i + 1}
    state_list.append(current_state)

print(state_list)  # 输出:[{'count': 1}, {'count': 2}, {'count': 3}]

这种方式代码更清爽,尤其适合状态结构简单的场景。

方法4:转成不可变对象(比如元组)

正如你想到的,把字典转成不可变的结构,比如由键值对组成的元组,这样每次存入列表的都是当前状态的“快照”——因为不可变对象不能被修改,自然不会后续被影响:

state = {"count": 0}
state_list = []

for i in range(3):
    state["count"] += 1
    # 把字典转成键值对元组的集合,作为快照存入列表
    state_snapshot = tuple(state.items())
    state_list.append(state_snapshot)

print(state_list)  # 输出:[(('count', 1),), (('count', 2),), (('count', 3),)]
# 后续需要转回字典的话,直接用 dict() 就行:dict(state_list[0])

补充说明

Python里其实没有真正的“按值传递”概念,所有传递都是传递引用。但我们可以通过创建新对象的方式,模拟出“保存当前值”的效果——本质就是让列表里的每个元素都是独立的对象,而不是同一个可变对象的引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:24:03