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

为嵌套字典分配随机列表时所有项均被赋值为最后生成的列表

Why does all keys in my parent dictionary reference the last sub-dictionary?

哦,这个坑我太熟了!你遇到的是Python里可变对象引用赋值的经典问题——每次把temp字典赋值给d[x]时,你并没有复制temp的内容,而是把temp这个字典对象的内存引用存到了d里。也就是说,d[0]、d[1]、d[2]其实都指向同一个字典实例,最后循环结束时,这个实例里的内容是最后一次循环修改的结果,所以所有键对应的都是最后那组随机列表。

你的问题代码

import numpy as np  # 补充你原代码遗漏的numpy导入

temp = {}
d = {}
for x in range(3):
    for i in range(3):
        temp[i] = list(np.random.randint(10, size=10))
    print(x)
    print(temp)
    d[x] = temp
    print(d[x])
    print("--------------------------")
print("The final dictionary: ", d)

运行输出

0 
{0: [1, 4, 1, 7, 3, 9, 3, 8, 1, 5], 1: [6, 5, 2, 0, 5, 0, 5, 9, 7, 1], 2: [7, 9, 3, 3, 5, 8, 6, 0, 6, 0]} 
{0: [1, 4, 1, 7, 3, 9, 3, 8, 1, 5], 1: [6, 5, 2, 0, 5, 0, 5, 9, 7, 1], 2: [7, 9, 3, 3, 5, 8, 6, 0, 6, 0]}
--------------------------
1 
{0: [0, 0, 7, 0, 0, 1, 9, 9, 2, 0], 1: [1, 5, 8, 7, 2, 9, 0, 8, 7, 9], 2: [8, 8, 4, 8, 1, 1, 1, 2, 4, 4]} 
{0: [0, 0, 7, 0, 0, 1, 9, 9, 2, 0], 1: [1, 5, 8, 7, 2, 9, 0, 8, 7, 9], 2: [8, 8, 4, 8, 1, 1, 1, 2, 4, 4]}
--------------------------
2 
{0: [5, 4, 7, 1, 1, 3, 0, 3, 6, 9], 1: [5, 9, 7, 8, 0, 7, 1, 7, 6, 9], 2: [4, 2, 6, 1, 3, 7, 2, 6, 4, 8]} 
{0: [5, 4, 7, 1, 1, 3, 0, 3, 6, 9], 1: [5, 9, 7, 8, 0, 7, 1, 7, 6, 9], 2: [4, 2, 6, 1, 3, 7, 2, 6, 4, 8]}
--------------------------
The final dictionary:  {0: {0: [5, 4, 7, 1, 1, 3, 0, 3, 6, 9], 1: [5, 9, 7, 8, 0, 7, 1, 7, 6, 9], 2: [4, 2, 6, 1, 3, 7, 2, 6, 4, 8]}, 1: {0: [5, 4, 7, 1, 1, 3, 0, 3, 6, 9], 1: [5, 9, 7, 8, 0, 7, 1, 7, 6, 9], 2: [4, 2, 6, 1, 3, 7, 2, 6, 4, 8]}, 2: {0: [5, 4, 7, 1, 1, 3, 0, 3, 6, 9], 1: [5, 9, 7, 8, 0, 7, 1, 7, 6, 9], 2: [4, 2, 6, 1, 3, 7, 2, 6, 4, 8]}}

问题根源

在Python中,字典是可变对象。当你执行d[x] = temp时,不是把temp的内容复制一份存到d[x],而是把temp这个对象的内存地址存了进去。所以d里的所有键都指向同一个temp字典,每次循环修改temp的内容,其实是在修改同一个对象,最后所有引用都会看到最后一次修改的结果。

解决方案

方法1:每次循环创建新的temp字典

把temp = {}放到外层循环内部,这样每次循环都会生成一个全新的字典对象,彻底避免引用冲突:

import numpy as np

d = {}
for x in range(3):
    temp = {}  # 每次循环新建独立字典
    for i in range(3):
        temp[i] = list(np.random.randint(10, size=10))
    print(x)
    print(temp)
    d[x] = temp
    print(d[x])
    print("--------------------------")
print("The final dictionary: ", d)

方法2:复制temp字典再赋值

如果不想移动temp的定义,可以用字典的copy()方法(或dict(temp))创建副本,这样d[x]存的是副本的引用,和原temp无关:

import numpy as np

temp = {}
d = {}
for x in range(3):
    for i in range(3):
        temp[i] = list(np.random.randint(10, size=10))
    print(x)
    print(temp)
    d[x] = temp.copy()  # 复制字典副本
    # 等价写法:d[x] = dict(temp)
    print(d[x])
    print("--------------------------")
print("The final dictionary: ", d)

两种方法都能解决问题,第一种更直观,适合大多数场景;第二种适合需要保留原temp对象的特殊情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:27:35