How to Merge Multiple Dicts with Same Key or Different Key

How to merge dicts, collecting values from matching keys?

assuming all keys are always present in all dicts:

ds = [d1, d2]
d = {}
for k in d1.iterkeys():
d[k] = tuple(d[k] for d in ds)

Note: In Python 3.x use below code:

ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = tuple(d[k] for d in ds)

and if the dic contain numpy arrays:

ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = np.concatenate(list(d[k] for d in ds))

Merge two dicts by same key

You almost had it, instead use + to append both lists:

{key: d1[key] + d2[key] for key in d1}

{'a': [2, 4, 5, 6, 8, 10, 12, 15],
'b': [1, 2, 5, 6, 9, 12, 14, 16],
'c': [0, 4, 5, 8, 10, 21, 23, 35]}

How to merge dictionaries of dictionaries?

This is actually quite tricky - particularly if you want a useful error message when things are inconsistent, while correctly accepting duplicate but consistent entries (something no other answer here does..)

Assuming you don't have huge numbers of entries, a recursive function is easiest:

def merge(a, b, path=None):
"merges b into a"
if path is None: path = []
for key in b:
if key in a:
if isinstance(a[key], dict) and isinstance(b[key], dict):
merge(a[key], b[key], path + [str(key)])
elif a[key] == b[key]:
pass # same leaf value
else:
raise Exception('Conflict at %s' % '.'.join(path + [str(key)]))
else:
a[key] = b[key]
return a

# works
print(merge({1:{"a":"A"},2:{"b":"B"}}, {2:{"c":"C"},3:{"d":"D"}}))
# has conflict
merge({1:{"a":"A"},2:{"b":"B"}}, {1:{"a":"A"},2:{"b":"C"}})

note that this mutates a - the contents of b are added to a (which is also returned). If you want to keep a you could call it like merge(dict(a), b).

agf pointed out (below) that you may have more than two dicts, in which case you can use:

reduce(merge, [dict1, dict2, dict3...])

where everything will be added to dict1.

Note: I edited my initial answer to mutate the first argument; that makes the "reduce" easier to explain

PS: In python 3, you will also need from functools import reduce

Merge multiple dicts with same key-value pair to one dict python

This is a perfect scenario to see the power of itertools.groupby
Note that I have assumed haps, state and ads will be present in all dictionaries, and will be similar in repetitions

from itertools import groupby

field_to_be_check = "state"
merger = ["city", "ads"]
merge_name = ["cities", "my_ads"]

data = [
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tirunelveli'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad4', 'city': 'nagerkoil'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tuticorin'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'madurai'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'chennai'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'palakad'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'guruvayor'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kolikodu'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kottayam'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'idukki'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Akola'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Washim'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Jalna'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Nanded'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Latur'}
]

#Function to make the merger lists
def process_group(group, merger_item):

item_set = set()
item_list = []
for item in group:
item_set.add(item[merger_item])

for item in item_set:
item_list.append({merger_item: item})

return item_list

#Group on haps, state and ads
grp = groupby(data,key=lambda x:(x[field_to_be_check]))
result = []

#Iterate through the group and build your result list
for model, group in grp:
cities_dict = {}

cities_dict[field_to_be_check] = model

group_list = list(group)

#Make the list for merger fields
for idx, name in enumerate(merger):
cities_dict[merge_name[idx]] = process_group(group_list, name)

result.append(cities_dict)

print(result)

The output will look like

[{'state': 'tamil nadu', 
'cities': [{'city': 'nagerkoil'}, {'city': 'tuticorin'}, {'city': 'chennai'}, {'city': 'madurai'}, {'city': 'tirunelveli'}],
'my_ads': [{'ads': 'ad4'}, {'ads': 'ad1'}]},
{'state': 'kerala',
'cities': [{'city': 'guruvayor'}, {'city': 'idukki'}, {'city': 'kottayam'}, {'city': 'palakad'}, {'city': 'kolikodu'}],
'my_ads': [{'ads': 'ad2'}]},
{'state': 'mumbai',
'cities': [{'city': 'Jalna'}, {'city': 'Nanded'}, {'city': 'Washim'}, {'city': 'Latur'}, {'city': 'Akola'}],
'my_ads': [{'ads': 'ad3'}]}]

Combining two dictionaries into one with the same keys?

This is a generic version. This can be used to create a dictionary with values as a list, even if the key is present in only one of them.

dic1 = {'A': 25, 'B': 41, 'C': 32}
dic2 = {'A': 21, 'B': 12, 'C': 62}
result = {}
for key in (dic1.keys() | dic2.keys()):
if key in dic1: result.setdefault(key, []).append(dic1[key])
if key in dic2: result.setdefault(key, []).append(dic2[key])

print(result)

Output

{'A': [25, 21], 'C': [32, 62], 'B': [41, 12]}

If you are using Python 2, for loop has to be changed like this:

for key in (dic1.viewkeys() | dic2.keys()):

Combine values of same keys in a list of dicts

bar = {
k: [d.get(k) for d in foo]
for k in set().union(*foo)
}

Things to google:

  • python list comprehension
  • python dict comprehension
  • python star
  • python dict get
  • python set union

Merge dictionaries with same key from two lists of dicts in python

Here is one of the approach:

a = {
"name":"harry",
"properties":[
{
"id":"N3",
"status":"OPEN",
"type":"energetic"
},
{
"id":"N5",
"status":"OPEN",
"type":"hot"
}
]
}
b = {
"name":"harry",
"properties":[
{
"id":"N3",
"type":"energetic",
"language": "english"
},
{
"id":"N6",
"status":"OPEN",
"type":"cool"
}
]
}

# Create dic maintaining the index of each id in resp dict
a_ids = {item['id']: index for index,item in enumerate(a['properties'])} #{'N3': 0, 'N5': 1}
b_ids = {item['id']: index for index,item in enumerate(b['properties'])} #{'N3': 0, 'N6': 1}

# Loop through one of the dict created
for id in a_ids.keys():
# If same ID exists in another dict, update it with the key value
if id in b_ids:
b['properties'][b_ids[id]].update(a['properties'][a_ids[id]])
# If it does not exist, then just append the new dict
else:
b['properties'].append(a['properties'][a_ids[id]])


print (b)

Output:

{'name': 'harry', 'properties': [{'id': 'N3', 'type': 'energetic', 'language': 'english', 'status': 'OPEN'}, {'id': 'N6', 'status': 'OPEN', 'type': 'cool'}, {'id': 'N5', 'status': 'OPEN', 'type': 'hot'}]}

How can I combine dictionaries with the same keys?

big_dict = {}
for k in dicts[0]:
big_dict[k] = [d[k] for d in dicts]

Or, with a dict comprehension:

{k: [d[k] for d in dicts] for k in dicts[0]}

merge dicts that have the same value for specific key

If lst is list from your question, you can do:

out = {}
for l in lst:
for d in l:
out.setdefault(d["tag"], {}).update(d)

print(list(out.values()))

Prints:

[
{"tag": "#2C00L02RU", "stamina": 233, "health": 200, "fame": 4, "moves": 4},
{"tag": "#8YG8RJV90", "stamina": 20, "health": 40, "fame": 2, "moves": 0},
{"tag": "#LQV2JCPR", "stamina": 154, "health": 100, "fame": 1, "moves": 6},
{"tag": "#9JQLPGLJJ", "stamina": 134, "health": 240, "fame": 3, "moves": 8},
]


Related Topics



Leave a reply



Submit