【问题标题】:Changing one dict value changes all values更改一个 dict 值会更改所有值
【发布时间】:2012-11-21 17:10:37
【问题描述】:

我在 Python 字典中看到了一些不寻常的行为:

import numpy as np
td =[np.Inf, 2, 3]
a = {}
# First initialize contents of dictionary to a list of values
for k in range(10):
    a[k] = td

# now I want to access the contents to modify them based on certain criteria 
for k in range(10):
    c = a[k]
    c[0] = k
    a[k] = c

据此,我希望每个字典键值的列表的每个第一项都会根据 (c[0] = k) 进行更改,但是,我最后得到的是 all 的值字典更新为k的最后一个值,如:

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

是我遗漏了什么,还是字典定义有问题?

我可以用不同的方式解决这个问题,让我的代码运行,但我对字典类为什么会这样表现感兴趣。

【问题讨论】:

    标签: python list dictionary


    【解决方案1】:

    发生这种情况是因为当您将值插入dict 时,您并没有插入一个全新的列表。您实际上是在插入对同一个旧列表的引用。因此,当您更改一个值时,您实际上是在更改该值指向的列表,从而更改所有值指向的列表。

    如果你真的想为每个值单独列出一个列表,那么你最好在插入时制作一个列表的浅表副本,如下所示:

    td =[np.Inf, 2, 3]
    for k in range(10):
        a[k] = td[:] #making a new list out of the old one
    

    现在,这将按您预期的方式工作

    for k in range(10):
        c = a[k]
        c[0] = k
        a[k] = c
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      因为每个键都获得相同的列表...要制作列表的浅表副本,请使用以下语法:

      for k in range(10):
          a[k] = td[:] 
      

      演示:

      >>> d = {}
      >>> el = [1, 2, 3]
      >>> d[0] = el
      >>> d[1] = el
      >>> map(id, d.values())
      [28358416, 28358416]
      

      【讨论】:

      • 谢谢,我的印象是每次新赋值都会重新初始化 (td) 的值,即旧值被破坏,但是,我现在知道字典的行为不同。 :)
      • @Nader 这不是字典......
      • 我明白,但是,我希望如果我在循环内更改 (el) 的值,那么附加的值也会相应地更改(例如 mylist = []; for i in range( 10): el=i; mylist.append(el)),在本例中是这样,但不是字典。
      【解决方案3】:

      当您在a[k] = td 行中引用td 时,实际上是在附加对原始列表的引用。该列表的任何修改在任何被引用的地方都是可见的。您需要使用the copy module 来创建一个新列表(或在循环本身中为每个条目构建一个新列表):

      for k in range(10):
          a[k] = [np.Inf, 2, 3]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-24
        相关资源
        最近更新 更多