使用for循环在字典内嵌套字典迭代

时间:2019-12-16 01:47:47

标签: python dictionary for-loop nested

有三种不同的嵌套字典:

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。 (请注意:格式为dict1dict2,即{'g1': {'s1': "xxxx",'s2':'xxxy'}},其中xxxxxxxy是低于指定条件的值。)

描述:键和值是通用的近似值。并且以上三个字典所需的期望输出也必须是嵌套字典,其字典中的条件为{{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)。

问题:正如我观察到的那样,它在更改时从所需的dict4dict1值覆盖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'}}},

1 个答案:

答案 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创建每个“层”的副本。