【问题标题】:Cannot update nested dictionary properly无法正确更新嵌套字典
【发布时间】:2021-08-20 19:50:28
【问题描述】:

我正在使用 Python 3.8.5

我已经创建了一些这样的对象:

class TestClass:
    def __init__(self, key, value):
        self.key=key
        self.value=value

test1 = TestClass(1, 'a')
test2 = TestClass(2, 'b')
test3 = TestClass(3, 'c')

test_list = [test1, test2, test3]

我想创建一个字典来跟踪这些对象的修改:

object_mapper = {
    'ClassNotRelevant': None,
    'TestClass': None,
    'ClassNotRelevant2': None,
}

test_dict = {test.key: object_mapper for test in test_list}

#output
{1: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
 2: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
 3: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}}

现在,我想为字典中的每个类设置 value 属性,如下所示:

#expected dictionary
#output
{1: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
 2: {'ClassNotRelevant': None, 'TestClass':'b', 'ClassNotRelevant2': None},
 3: {'ClassNotRelevant': None, 'TestClass':'c', 'ClassNotRelevant2': None}}

我正在尝试执行以下操作:

for test in test_list:
    test_dict[test.key]['TestClass']= test.value

但输出是:

{1: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
 2: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
 3: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None}}

我尝试了不同的解决方案:Updating nested dictionaries when data has existing key

但是一切正常,我做错了什么?

【问题讨论】:

  • 您只创建了一个object_mapper 字典,用于test_dict 中的所有条目。您需要每个条目都有自己的字典副本。 test_dict = {test.key: object_mapper.copy() for test in test_list} 也是如此。这将为每个条目执行object_mapper 的浅拷贝。

标签: python dictionary


【解决方案1】:

这是解决问题的代码。它将为每次迭代创建object_mapper 的副本。

test_dict = {test.key: object_mapper.copy() for test in test_list}
for test in test_list:
    test_dict[test.key]['TestClass']=test.value
print(test_dict)

【讨论】:

    【解决方案2】:

    问题出在这里

    当你这样做时

    test_dict = {test.key: object_mapper for test in test_list}

    输出是

    {1: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
     2: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None},
     3: {'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}}
    

    这个{'ClassNotRelevant': None, 'TestClass': None, 'ClassNotRelevant2': None}是同一个对象(object_mapper)对应于key `1 2 3'

    所以当你使用这个更新时:

    for test in test_list:
        test_dict[test.key]['TestClass']= test.value
    

    这会更新object_mapper 对象,

    第一次迭代后:

    {1: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
     2: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None},
     3: {'ClassNotRelevant': None, 'TestClass': 'a', 'ClassNotRelevant2': None}}
    

    第二次迭代

    {1: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None},
     2: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None},
     3: {'ClassNotRelevant': None, 'TestClass': 'b', 'ClassNotRelevant2': None}}
    
    

    第三次迭代

    {1: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
     2: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None},
     3: {'ClassNotRelevant': None, 'TestClass': 'c', 'ClassNotRelevant2': None}}
    
    

    所以不是

    test_dict = {test.key: object_mapper for test in test_list}

    使用

    test_dict = {test.key: object_mapper.copy() for test in test_list}

    这将为每个条目创建shallow_copy of object_mapper 对象,而不是将object_mapper 对象本身放在那里。

    【讨论】:

    • 有点 TL;DR 但最终是正确的建议。
    猜你喜欢
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    相关资源
    最近更新 更多