I have a dictionary like this. Length may vary:
dct: dict = {'first': {'val1': {'subval1': 1, 'subval2': 555}, 'val2': 2, 'val3': 3}, 'second': {'val1': 1, 'val2': 2, 'val3': 3}}
I have a "path" to a value and a new content for that value:
path = ['first', 'val1', 'subval1', 1000]
How can I change the value in the dictionary? The "path" can change, the values in it too. It could be:
path = ['third', 'firstval', 'val3', 'subval2', 999]
or something else.
CodePudding user response:
You can write a recursive function to create dictionaries from your paths and then update
your initial dictionary:
my_dict = {'first': {'val1': {'subval1': 1, 'subval2': 555}, 'val2': 2, 'val3': 3}, 'second': {'val1': 1, 'val2': 2, 'val3': 3}}
update_path = ['first', 'val1', 'subval1', 1000]
def create_dict_from_path(l):
if len(l) > 1:
return {l[0]: create_dict_from_path(l[1:])}
else:
return l[0]
update_dict = create_dict_from_path(update_path)
my_dict.update(update_dict)
print(my_dict)
Output:
{'first': {'val1': {'subval1': 1000}}, 'second': {'val1': 1, 'val2': 2, 'val3': 3}}
Edit: if you want to go until the deepest level of your dictionary in order to keep all key/value pairs, the recursive function will be a bit more intricated:
def update_dict_from_path(d, l):
if len(l) > 2 and l[0] in d:
update_dict_from_path(d[l[0]], l[1:])
elif len(l) == 2 and l[0] in d:
d[l[0]] = l[1]
update_dict_from_path(my_dict, update_path)
print(my_dict)
Output:
{'first': {'val1': {'subval1': 1000, 'subval2': 555}, 'val2': 2, 'val3': 3}, 'second': {'val1': 1, 'val2': 2, 'val3': 3}}
Edit2: you might wanna check if you're not overwriting nested dictionaries with scalar values in case the same key is found at different levels: elif len(l) == 2 and l[0] in d and not isinstance(d[l[0]], dict):