【问题标题】:Python - FOR loop not writing correct values in nested dictionariesPython - FOR循环没有在嵌套字典中写入正确的值
【发布时间】:2016-09-26 15:28:43
【问题描述】:

希望有人可以帮助我,因为我的研究都没有帮助我。我有一本简单的字典:

mydict = {
    1: {1: 'Foo'},
    2: {1: 'Bar'}
    }

我正在复制每个键/值对以分配新的键值:

nextKey = len(mydict) + 1
for currKey in range(len(mydict)):
    mydict[nextKey] = mydict[currKey + 1]
    nextKey += 1

这给了我一个mydict

{
    1: {1: 'Foo'},
    2: {1: 'Bar'},
    3: {1: 'Foo'},
    4: {1: 'Bar'},
    }

我现在想为所有现有的嵌套字典添加一个新的键值对。每个的键应该是 '2' 并且每个嵌套字典的值应该增加:

newValue = 1
for key in mydict:
    mydict[key][2] = newValue
    newValue += 1

我期待:

{
    1: {1: 'Foo', 2: 1},
    2: {1: 'Bar', 2: 2},
    3: {1: 'Foo', 2: 3},
    4: {1: 'Bar', 2: 4},
    }

但这给了我一个mydict

{
    1: {1: 'Foo', 2: 3},
    2: {1: 'Bar', 2: 4},
    3: {1: 'Foo', 2: 3},
    4: {1: 'Bar', 2: 4},
    }

我使用了我正在使用的 IDE 的可视化工具,在我运行循环以复制键/值对之后,新键似乎只是引用了复制的值而不是实际包含它,也许这有一些东西和它有什么关系?

IDE Visualisation

谁能帮忙/解释一下?

【问题讨论】:

  • “新键只是​​引用重复的值,而不是实际包含它”。是的,这就是答案。\

标签: python for-loop dictionary nested


【解决方案1】:

这是因为在您的第一个循环中,您没有复制嵌套字典,而只是添加了对相同字典的新引用。

也许可以举一个更清楚的例子:如果你要在两个循环后跳出第二个循环(使用你的原始代码),你的输出将是:

{1: {1: 'Foo', 2: 1}, 
2: {1: 'Bar', 2: 2}, 
3: {1: 'Foo', 2: 1}, 
4: {1: 'Bar', 2: 2}}

所以你可以像这样修复你的第一个循环:

for currKey in range(len(mydict)):
    mydict[nextKey] = mydict[currKey + 1].copy()
    nextKey += 1

copy() 函数会创建字典的真实副本,以便您可以在第二个循环中访问这 4 个不同的字典。

【讨论】:

    【解决方案2】:

    你的假设是正确的。最小的例子:

    >>> a = {1: {"a": "A"}, 2:{"b": "B"}}
    >>> a[3] = a[1]
    >>> a
    {1: {'a': 'A'}, 2: {'b': 'B'}, 3: {'a': 'A'}}
    >>> id(a[3])                           # a[1] and a[3] are the same object
    140510365203264
    >>> id(a[1])
    140510365203264
    >>> a[1]['a'] = "changed"              # so changing one affects the "oter one"
    >>> a
    {1: {'a': 'changed'}, 2: set(['B', 'b']), 3: {'a': 'changed'}}
    

    如果你想复制对象,有几种方法可以做到这一点:

    • 对于列表:new = old[:],使用切片符号
    • 词典:dict.copy()
    • 另见copy module

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多