Here is a simple recursive solution. This solution is generic enough to be able to support any future changes in the structure of your dictionary, you can even use this for purposes other than this list of countries. By taking advantage of the mutability property of dict
and list
, we can pass it around each recursive call and perform:
- If the element in
lhs
(left-hand side, here is List1
) doesn't appear yet in the rhs
(right-hand side, here is result
), copy it as is.
- If the element in
lhs
already appears in rhs
, do a recursive call to merge the inner elements.
- If the value in
lhs
is a list, add it to the rhs
.
import copy
import json
List1= [
{'Europe': {'DE': {'Berlin': ['Jack']}}},
{'Europe': {'DE': {'KL': ['Paul']}}},
{'Asia': {'PH': {'Manila': ['Jose', 'Rizal']}}},
{'Europe': {'FR': {'Paris': ['Jean', "Pierre"]}}},
{'Asia': {'PH': {'Manila': ['Andres']}}},
{'Asia': {'KH': {'Siem Reap': ['Angkor']}}},
{'Europe': {'DE': {'Berlin': ['Jill']}}},
{'Asia': {'PH': {'Cebu': ['Lapulapu']}}},
{'Asia': {'PH': {'Manila': ['Bonifacio']}}},
{'Europe': {'ES': {'Valencia': ['Paella']}}},
{'Asia': {'KH': {'Phnom Penh': ['Wat']}}},
{'Europe': {'ES': {'Valencia': ['Me gusta mucho!']}}},
{'Asia': {'PH': {'Palawan': ['Beach']}}},
{'Asia': {'PH': {'Palawan': ['Cave']}}},
{'Asia': {'PH': {'Palawan': []}}},
]
result = {}
def merge(lhs, rhs):
if isinstance(lhs, dict):
for key, value in lhs.items():
if key not in rhs:
rhs[key] = copy.deepcopy(value) # Thanks to @sabik for the code review (see comments section). To avoid updating the source data List1, here we would perform a deep copy instead of just <rhs[key] = value>.
else:
merge(value, rhs[key])
elif isinstance(lhs, list):
rhs.extend(lhs)
for item in List1:
merge(item, result)
print(json.dumps(result, indent=4))
Output:
{
"Europe": {
"DE": {
"Berlin": [
"Jack",
"Jill"
],
"KL": [
"Paul"
]
},
"FR": {
"Paris": [
"Jean",
"Pierre"
]
},
"ES": {
"Valencia": [
"Paella",
"Me gusta mucho!"
]
}
},
"Asia": {
"PH": {
"Manila": [
"Jose",
"Rizal",
"Andres",
"Bonifacio"
],
"Cebu": [
"Lapulapu"
],
"Palawan": [
"Beach",
"Cave"
]
},
"KH": {
"Siem Reap": [
"Angkor"
],
"Phnom Penh": [
"Wat"
]
}
}
}