user5927494
user5927494

Reputation: 129

Merging dictionaries for same key in Python

This is the code that I have so far in trying to look through three dictionaries that have the same key, and add its appropriate values. If no key exists, I would like for code to add a zero.

#!/usr/bin/env python
import sys
from operator import itemgetter 
import csv
import ast 
from collections import defaultdict

super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}

for d in (d1, d2, d3):
   for key, value in d.iteritems():
     super_dic.setdefault(key, []).append(value)
print super_dic

Output of super_dic built:

{'a': [2, 3], 'c': [3, 3], 'b': [5, 4], 'd': [6, 4]}

However, I would like my end result to be:

{'a':[2, 3, 0], 'c':[3,3,0], 'b':[5,0,4],'d':[6,0,4]} 

the order of values matters

Any help/feedback is much appreciated. Been fighting this for a while now and all approaches tried do not built the right master dictionary at end.

*Please note this is not a duplicate question because questions asked with merging dictionaries in Python, all overlook the fact to add the zero if key item does not exist. *

Upvotes: 2

Views: 199

Answers (3)

Garrett R
Garrett R

Reputation: 2662

I'd do it like this. Get all the keys in a set, create a defaultdict with a list function. And then iterate over all keys for all dictionaries.

all_keys = set(d1).union(d2).union(d3)

merged_dict = defaultdict(list)
for d in (d1,d2,d3):
    for key in all_keys:
        merged_dict[key] += d.get(key, 0),

print merged_dict

Upvotes: 1

MSeifert
MSeifert

Reputation: 152657

I found a somewhat (awkward) solution:

from collections import defaultdict

super_dic={}
d1 = {'a':2, 'b':5, 'c':3, 'd':6}
d2 = {'a':3, 'c':3}
d3 = {'b':4, 'd':4}

# Counter because it might be that there is some element only present in a later dict.
# And we need to compare the current list lengths in each turn
i = 0
for d in (d1, d2, d3):
    for key in d:
        # It might be that a key wasn't present before so set default to [0]*i
        super_dic.setdefault(key, [0]*i).append(d[key])
    # Increment i so we can compare the list lengths:
    i += 1
    # Append 0 for every key that wasn't appended in this turn:
    for key in super_dic:
        if len(super_dic[key]) < i:
            super_dic[key].append(0)
print(super_dic)

{'b': [5, 0, 4], 'a': [2, 3, 0], 'd': [6, 0, 4], 'c': [3, 3, 0]}

The explanation is inside in-code comments I hope it's understandable otherwise I'll elaborate them further. Just comment if anything is unclear.

Upvotes: 0

timgeb
timgeb

Reputation: 78690

To be more general, let's assume you have a list of dictionaries called dicts.

>>> dicts = [d1, d2, d3]
>>> allkeys = set(x for d in dicts for x in d.keys())    
>>> super_dic = {k:[d.get(k, 0) for d in dicts] for k in allkeys}
>>> super_dic
{'a': [2, 3, 0], 'c': [3, 3, 0], 'b': [5, 0, 4], 'd': [6, 0, 4]}

Upvotes: 5

Related Questions