Mico
Mico

Reputation: 413

Pythonic way to get the union of dictionaries

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

Answers (2)

user2390182
user2390182

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

Kasravnd
Kasravnd

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

Related Questions