Home > front end >  How to correctly update the values of list types in a Python nested dictionary?
How to correctly update the values of list types in a Python nested dictionary?

Time:11-05

The case is that I'd like to build a nested dictionary with the structure like the following

{'a': {'1': [], '2': [], '3': [], '4': []},
 'b': {'1': [], '2': [], '3': [], '4': []},
 'c': {'1': [], '2': [], '3': [], '4': []}}

and the initiation part is

keys = ['a','b','c']
subkeys = ['1','2','3','4']
target_dict = dict.fromkeys(keys, {key: [] for key in subkeys})

and then, I want to update the values of a subkey, like target_dict['a']['1'] = 1, which i only want to set the entry "a-1" to 1, and leave other values blank. However, the "a-1", "b-1", and "c-1" all update simultaneously. Leading to the result as

{'a': {'1': 1, '2': [], '3': [], '4': []},
 'b': {'1': 1, '2': [], '3': [], '4': []},
 'c': {'1': 1, '2': [], '3': [], '4': []}}

what's the reason of this case, and how should I fix it? Thanks.

CodePudding user response:

The problem is that target_dict['a'] target_dict['b'] and target_dict['c'] seems to be keeping the same reference. Try changing your code to

target_dict = {k: {key: [] for key in subkeys} for k in keys}

CodePudding user response:

You're giving each key the same object (a dict) as a value. Regardless of which key you use to access the dict and modify it, there's only one dict, so it's reflected for all the other keys.

Creating a dict for each key solves the problem:

>>> keys = ['a','b','c']
>>> subkeys = ['1','2','3','4']
>>> target_dict = {key: {subkey: [] for subkey in subkeys} for key in keys}
>>> target_dict
{'a': {'1': [], '2': [], '3': [], '4': []}, 'b': {'1': [], '2': [], '3': [], '4': []}, 'c': {'1': [], '2': [], '3': [], '4': []}}
>>> target_dict['a']['1'].append(1)
>>> target_dict
{'a': {'1': [1], '2': [], '3': [], '4': []}, 'b': {'1': [], '2': [], '3': [], '4': []}, 'c': {'1': [], '2': [], '3': [], '4': []}}

CodePudding user response:

keys = ['a','b','c']
subkeys = ['1','2','3','4']

temp = lambda x: dict(zip(subkeys, [[1] if x == "a" and i == 0 else [] for i in range(len(subkeys))]))
target_dict = {k:v for k, v in zip(keys, [temp(key) for key in keys])}
print(target_dict)
# {'a': {'1': [1], '2': [], '3': [], '4': []}, 'b': {'1': [], '2': [], '3': [], '4': []}, 'c': {'1': [], '2': [], '3': [], '4': []}}
  • Related