Reputation: 49
I have two dictionaries:
dict1 = {'cm': {'fill': {'user': {'registration': {'flag': 'f'}}}}}
dict2 = {'cm': {'fill': {'user': {'url': 'www.example.com'}}}}
The output I want:
dict3 = {'cm': {'fill': {'user':{'registration': {'flag': 'f'}}, {'url': 'www.example.com'}}}
Here is what I have tried so far:
dict3 = {**dict1, **dict2} # This does not work. It only gives me a `dict1`.
The problem is that dict1
and dict2
can have many embedded keys.
Any idea how to do this?
Upvotes: 2
Views: 133
Reputation: 71451
You can use recursion while zip
ing the data:
dict1 = {'cm': {'fill': {'user': {'registration': {'flag': 'f'}}}}}
dict2 = {'cm': {'fill': {'user': {'url': 'www.example.com'}}}}
def update_dict(d1, d2):
return {a:update_dict(b, d) if a == c and list(b.keys())[0] == list(d.keys())[0] else {**b, **d} for [a, b], [c, d] in zip(d1.items(), d2.items())}
Output:
{'cm': {'fill': {'user': {'registration': {'flag': 'f'}, 'url': 'www.example.com'}}}}
Upvotes: 0
Reputation: 164653
If the structure of your dictionaries is consistent, you can use collections.defaultdict
with a nested approach.
It's possible to convert the nested defaultdict
to regular dict
objects. But this may not be necessary for your use case.
from collections import defaultdict
dict1 = {'cm': {'fill': {'user': {'registration': {'flag': 'f'}}}}}
dict2 = {'cm': {'fill': {'user': {'url': 'www.example.com'}}}}
rec_dd = lambda: defaultdict(rec_dd)
d = rec_dd()
for i in [dict1, dict2]:
d['cm']['fill']['user'].update(i['cm']['fill']['user'])
# defaultdict(<function __main__.<lambda>>,
# {'cm': defaultdict(<function __main__.<lambda>>,
# {'fill': defaultdict(<function __main__.<lambda>>,
# {'user': defaultdict(<function __main__.<lambda>>,
# {'registration': {'flag': 'f'},
# 'url': 'www.example.com'})})})})
Upvotes: 1
Reputation: 77837
Correct: that merge won't do what you want. You have accumulation to do multiple levels down. I suspect that the easiest way for you to get what you want -- merging at unspecified (arbitrary) depth -- is to write a recursive routine to do the merge you want.
def dict_merge(d1, d2):
for key in d1:
if key in d2:
one_merge = dict_merge(d1[key], d2[key])
else:
one_merge = d1[key]
for ... # also pick up keys in d2 that are not in d1.
I'll leave it to you whether to handle this logic with set intersection and difference.
Upvotes: 2