有三种不同的嵌套字典:
dict1={'g1': {'s1': 'checked', 's2': '0', 'Both':'checked'}, 'g2': {'s1': '0', 's2':'checked', 'Both': 'checked'}, 'g3': {'s1': 'checked', 's2': 'checked', 'Both': 'checked'}}
dict2={'g1': {'s1': '11', 's2': '', 'Both': '13'}, 'g2': {'s1': '', 's2': '22', 'Both':'23'}, 'g3': {'s1':'31', 's2': '32', 'Both': '33'}}
dict3={"s1": {"PS":'value1'}, "s2": {"PS": 'value2'}, "Both": {"PS": 'value3'}}
所需的嵌套字典为dict4
。 (请注意:格式为dict1
或dict2
,即{'g1': {'s1': "xxxx",'s2':'xxxy'}}
,其中xxxx
和xxxy
是低于指定条件的值。)
描述:键和值是通用的近似值。并且以上三个字典所需的期望输出也必须是嵌套字典,其字典中的条件为{{1}中的条件if value=='checked'
,然后是具有新键dict1
的{{1}}和{{1 }}具有相同的嵌套键,必须添加到具有dict3
的父键的所需嵌套字典'Msg'
中。
我的代码:
dict2
上面的代码输出错误:(错误的dict4
值)
dict1
正确且理想的输出:(具有正确的dict4={} # declaring desired dictionary
for nkey,nvalue in dict1.items():
tempDict={} #temporary dictionary to store all checked from dict1
for key,value in nvalue.items():
if value=='checked':
tempDict[key]=dict3[key]
tempDict[key]['Msg']=dict2[nkey][key]
#in prescribed format assigning dict4
dict4[nkey]=tempDict
)
'Msg'
按照上面的代码,我试图将dict4 = {'g1': {'s1': {'PS': 'value1', 'Msg': '31'}, 'Both': {'PS': 'value3', 'Msg': '33'}}, 'g2': {'s2': {'PS': 'value2', 'Msg': '32'}, 'Both': {'PS': 'value3', 'Msg': '33'}}, 'g3': {'s1': {'PS': 'value1', 'Msg': '31'}, 's2': {'PS': 'value2', 'Msg': '32'}, 'Both': {'PS': 'value3', 'Msg': '33'}}}
中所有检查的内容存储到一个临时字典中,然后添加键'Msg'
(新键)和dict4 = {'g1': {'s1': {'PS': 'value1', 'Msg': '11'}, 'Both': {'PS': 'value3', 'Msg': '13'}}, 'g2': {'s2': {'PS': 'value2', 'Msg': '22'}, 'Both': {'PS': 'value3', 'Msg': '23'}}, 'g3': {'s1': {'PS': 'value1', 'Msg': '31'}, 's2': {'PS': 'value2', 'Msg': '32'}, 'Both': {'PS': 'value3', 'Msg': '33'}}}
中的值,然后分配dict1
以所需的格式(来自'Msg'
的键和来自临时字典的值,即dict2
)。
问题:正如我观察到的那样,它在更改时从所需的dict4
和dict1
值覆盖tempDict
,然后在for循环内反映'Msg'
的值(因为我已经通过在所有阶段打印值来调试代码了。
请澄清并提出可能的解决方案,以及为什么在dict4
上更改值时,为什么它反映到tempDict
中已分配给先前键值的位置,即dict4
更改时tempDict
代表dict4
,然后它也更改了tempDict
和'Msg'
中的值。
我尝试用g3
方法代替g1
,然后g2
的输出如下:
tempDict.clear()
上面的输出:(错误)
tempDict={}
是否存在从值问题分配的内存或我写错逻辑的地方?
正确且理想的输出:(具有正确的dict4
)
dict4={} # declaring desired dictionary
for nkey,nvalue in dict1.items():
tempDict={} #temporary dictionary to store all checked from dict1
for key,value in nvalue.items():
if value=='checked':
tempDict[key]=dict3[key]
tempDict[key]['Msg']=dict2[nkey][key]
#in prescribed format assigning dict4
dict4[nkey]=tempDict
tempDict.clear()
代码3 :(相同的输出)
dict4 = {'g1': {}, 'g2': {}, 'g3': {'s1': {'PS': 'value1', 'Msg': '31'}, 's2': {'PS': 'value2', 'Msg': '32'}, 'Both': {'PS': 'value3', 'Msg': '33'}}},
答案 0 :(得分:1)
问题在于Python的dict
类型是可变类型。使用tempDict[key]=dict3[key]
,您可以将对现有dict3[key]
的“引用”放入tempDict[key]
中。如果您通过从dict
的引用访问对象来更改对象,则这些更改将随处可见(因为dict3[key]
和tempDict[key]
都引用同一对象)。>
换句话说,您可以通过“外部” dict
中的“内部” dict
引用来访问它,因此将对“内部” dict
进行任何修改“可见”以您用来访问它的任何方式。毕竟,这只是一个对象。在copy
之后,您有两个对象(两个“内部” dict
),两个“外部” dict
分别引用了它们。
有关Python中可变/不可变类型的更多信息,例如Immutable vs Mutable types。
关于解决方案:好消息,如果您不希望dict3[key]
和tempDict[key]
都引用同一个对象,则可以通过dict.copy
方法创建一个副本。因此,在您的第一个代码中,您唯一需要更改的就是
tempDict[key]=dict3[key]
到
tempDict[key]=dict3[key].copy()
您将获得所需的输出。
例如,如果您的dict
包含要更改的其他可变类型,则必须使用copy.deepcopy
创建每个“层”的副本。