Reputation: 413
Is there a better/pythonic way to do the following:
I have a function that merges dictionaries:
def merge_dicts(a, *dict_args):
for dictionary in dict_args:
for k, v in dictionary.items():
if k not in a:
a[k] = v
return a
Here is a sample run:
a = {'A': 1, 'B': 2}
b = {'B': 3, 'C': 4}
c = merge_dicts(a, b) # {'A': 1, 'B': 2, 'C': 4}
I am using python2.7.
Upvotes: 2
Views: 1299
Reputation: 73460
You can use update
. Since the earlier dicts have priority you have to update in reverse order, and update with a
last:
def merge_dicts(a, *dict_args):
d = {}
for dictionary in reversed(dict_args):
d.update(dictionary)
d.update(a)
return d
Or as a one-liner, using itertools.chain
:
from itertools import chain
def merge_dicts(a, *dict_args):
# chain (key, value) items in order of increasing priority
return dict(chain.from_iterable(d.iteritems() for d in dict_args[::-1]+(a,)))
> merge_dicts(a, b)
{'A': 1, 'C': 4, 'B': 2}
If I may add, why not remove a
from the function signature altogether:
def merge_dicts(*dict_args):
return dict(chain.from_iterable(d.iteritems() for d in dict_args[::-1]))
# If you provide 0 or 1 dict,
# this will return an empty dict or the single dict (a copy thereof) itself
Upvotes: 3
Reputation: 107287
You don't need to check the existence of keys in dictionaries, since you want to preserve the first key you can use a dict comprehension by looping through the list of dictionaries backward:
{k: v for d in list_of_dict[::-1] for k, v in d.items()}
Python will replace the existence keys with new ones, each time it encounter a duplicate one, and since you are looping through the list backward, it will comes up with the first keys in your aggregated dictionary.
Based on your example:
>>> {k: v for d in l[::-1] for k, v in d.items()}
{'A': 1, 'C': 4, 'B': 2}
Upvotes: 1