Rotem Bartuv
Rotem Bartuv

Reputation: 133

Merge two dictionary in python with different keys

I have two dictionaries:

dict_conv
Out[162]: 
{'Alanine, aspartate and glutamate metabolism': 4,
 'Ascorbate and aldarate metabolism': 4,
 'Benzoate degradation': 6,
 'Biosynthesis of antibiotics': 16}

dict_org
Out[163]: 
{'Amino sugar and nucleotide sugar metabolism': 5,
 'Arginine and proline metabolism': 4,
 'Biosynthesis of antibiotics': 11,
 'Biosynthesis of secondary metabolites': 21}

and I want to combine them. I did like this:

def mergeDict(dict_conv, dict_org):
   ''' Merge dictionaries and keep values of common keys in list'''
   dict3 = {**dict_conv, **dict_org}
   for key, value in dict3.items():
       if key in dict_conv and key in dict_org:
               dict3[key] = [value , dict_conv[key]]
   return dict3

dict3 = mergeDict(dict_conv, dict_org)

and got this dict:

dict3
Out[164]: 
{'Alanine, aspartate and glutamate metabolism': 4,
 'Ascorbate and aldarate metabolism': 4,
 'Benzoate degradation': 6,
 'Biosynthesis of antibiotics': [11, 16],
 'Biosynthesis of secondary metabolites': [21, 26]}

I want to have two values (in a list) for every key. If the key is not in one of the dictionaries I want it to write 0, like this:

dict3
    Out[164]: 
    {'Alanine, aspartate and glutamate metabolism': [4,0],
     'Amino sugar and nucleotide sugar metabolism': [0,5],
     'Ascorbate and aldarate metabolism': [4,0],
     'Benzoate degradation': [6,0],
     'Biosynthesis of antibiotics': [11, 16],
     'Biosynthesis of secondary metabolites': [0,21]}

(the first value represent the "dict_conv" value, and the second represent the "dict_org" value)

what should I add to the mergeDict function?

thank you :)

Upvotes: 0

Views: 223

Answers (2)

user9706
user9706

Reputation:

You could also just set the value unconditionally with:

from pprint import pprint

...

for key in dict3.keys():
    dict3[key] = [dict_conv.get(key, 0), dict_org.get(key, 0)]
....

pprint(dict3)
{'Alanine, aspartate and glutamate metabolism': [4, 0],
 'Amino sugar and nucleotide sugar metabolism': [0, 5],
 'Arginine and proline metabolism': [0, 4],
 'Ascorbate and aldarate metabolism': [4, 0],
 'Benzoate degradation': [6, 0],
 'Biosynthesis of antibiotics': [16, 11],
 'Biosynthesis of secondary metabolites': [0, 21]}

Upvotes: 0

Thierry Lathuille
Thierry Lathuille

Reputation: 24232

You could simply build a set of all keys, then create the lists using the get method of the dicts, with a default value of 0:

def merge(d1, d2):
    keys = set(d1.keys()) | set(d2.keys())
    return {key: [d1.get(key, 0), d2.get(key, 0)] for key in keys}

As suggested by @Stephan B, the first line can be written in a shorter way:

keys = set(d1) | set(d2)

because iterating on a dict iterates on its keys, or as:

keys = set(d1).union(d2)

because the argument to union, intersection and so on only needs to be an iterable, not necessarily a set.

Sample run with your data:

d1 = {'Alanine, aspartate and glutamate metabolism': 4,
     'Ascorbate and aldarate metabolism': 4,
     'Benzoate degradation': 6,
     'Biosynthesis of antibiotics': 16}

d2 = {'Amino sugar and nucleotide sugar metabolism': 5,
     'Arginine and proline metabolism': 4,
     'Biosynthesis of antibiotics': 11,
     'Biosynthesis of secondary metabolites': 21}

print(merge(d1, d2))

Output:

{'Biosynthesis of antibiotics': [16, 11], 
'Amino sugar and nucleotide sugar metabolism': [0, 5], 
'Arginine and proline metabolism': [0, 4], 
'Alanine, aspartate and glutamate metabolism': [4, 0], 
'Ascorbate and aldarate metabolism': [4, 0], 
'Benzoate degradation': [6, 0], 
'Biosynthesis of secondary metabolites': [0, 21]}

Upvotes: 4

Related Questions