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

循环填充字典时列表值随迭代变更的原因咨询

字典值为列表时的引用异常问题

预期目标

想要构建一个键为整数、值为对应整数列表的字典,预期结果示例:

{0:[0], 1:[0,1], 2:[0,1,2], 3:[0,1,2,3] ...}

尝试的代码

dictfinal = {}
List = []
for i in range(0,3):
    List.append(i)
    dictfinal[i] = List
    print(List)
    print(dictfinal)

实际输出结果

[0]
{0: [0]}
[0, 1]
{0: [0, 1], 1: [0, 1]}
[0, 1, 2]
{0: [0, 1, 2], 1: [0, 1, 2], 2: [0, 1, 2]}

可以看到,每次迭代时已定义的字典键对应的值也会同步变更。

对比情况(值为整数时正常)

当将字典值改为整数时,问题消失:

dictfinal = {}
List = []
for i in range(0,3):
      List.append(i)
      dictfinal.update({i:i})
      print(List)
      print(dictfinal)

输出结果符合预期:

[0]
{0: 0}
[0, 1]
{0: 0, 1: 1}
[0, 1, 2]
{0: 0, 1: 1, 2: 2}

问题原因

核心原因是Python里可变对象和不可变对象的引用逻辑不一样:

  • 列表是可变对象:你只创建了一个List列表对象,字典里所有键存的都是指向这个列表的「内存地址」(也就是引用)。每次List.append(i)都是在修改同一个列表,所以所有字典键对应的列表都会跟着变——它们本来就是同一个东西的不同别名而已。
  • 整数是不可变对象:整数一旦创建就不能修改,当你给字典赋值i:i时,每个键对应的都是独立的整数对象,不存在共享引用的问题,所以各键的值互不影响。

解决方法

要实现预期效果,需要确保每个字典键对应的是独立的列表对象,有几种常见写法:

方法1:每次循环新建列表

dictfinal = {}
for i in range(0, 3):
    # 每次循环创建新的列表,避免共享引用
    current_list = list(range(i+1))
    dictfinal[i] = current_list
    print(current_list)
    print(dictfinal)

方法2:使用列表拷贝

如果需要基于之前的列表扩展,可以用切片或copy()方法创建新列表:

dictfinal = {}
List = []
for i in range(0, 3):
    List.append(i)
    # 拷贝当前List的内容,生成新的列表对象
    dictfinal[i] = List.copy()  # 或者 List[:]
    print(List)
    print(dictfinal)

方法3:字典推导式(简洁写法)

dictfinal = {i: list(range(i+1)) for i in range(0, 3)}
print(dictfinal)

以上方法的输出结果都会符合预期:{0: [0], 1: [0, 1], 2: [0, 1, 2]}


内容的提问来源于stack exchange,提问作者Matthew Rhys Dixon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:47:46