221

How do you calculate the union of two dict objects in Python, where a (key, value) pair is present in the result iff key is in either dict (unless there are duplicates)?

For example, the union of {'a' : 0, 'b' : 1} and {'c' : 2} is {'a' : 0, 'b' : 1, 'c' : 2}.

Preferably you can do this without modifying either input dict. Example of where this is useful: Get a dict of all variables currently in scope and their values

Community
  • 1
  • 1
Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
  • 3
    @RikPoggi: The other question, despite its title, is asking about what the `**d2` *syntax* is. It happens to provide an answer to this question. – Mechanical snail Mar 23 '12 at 04:52
  • 7
    `merged_dict = {**dict1, **dict2}` in python 3.5+ (to save you a trip to the other link or from using the buggy solution accepted here which fails if your keys aren't strings). – Nathan May 11 '19 at 01:14
  • `merged_dict = dict(**a,**b,**c,**d)` worked for me too – Charlie Parker Jul 23 '19 at 21:10
  • 1
    Looks like the correct solution will come in Python 3.9, see https://www.python.org/dev/peps/pep-0584/ – Attila123 Apr 23 '20 at 13:12
  • 2
    Python 3.9 : `a = {1: 'a', 2: 'b', 3: 'c'}; b = {4: 'd', 5: 'e'}; c = a | b` – Pygirl Jun 17 '20 at 06:35
  • do `{**d1, **d2}`. For details see: https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python – Charlie Parker Jul 13 '20 at 21:17

4 Answers4

170

This question provides an idiom. You use one of the dicts as keyword arguments to the dict() constructor:

dict(y, **x)

Duplicates are resolved in favor of the value in x; for example

dict({'a' : 'y[a]'}, **{'a', 'x[a]'}) == {'a' : 'x[a]'}
Community
  • 1
  • 1
Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
  • 16
    "Simple is better than complex." :) You should use `update` member function of `dict`. – shahjapan Aug 06 '12 at 18:51
  • 29
    How is `tmp = dict(y); tmp.update(x); do_something(tmp)` simpler? – Mechanical snail Aug 07 '12 at 06:04
  • 9
    @shahjapan This is not complex, this is great use of Python dict structure. And this is different from update (this solution is not updating anything). – lajarre Sep 13 '12 at 09:09
  • 4
    @lajarre: I agree, As in this case OP doesn't want to update any of the dicts - its a nice way to create a new `dict` based on existing dicts. – shahjapan Sep 13 '12 at 12:09
  • 20
    It is not 'nice', it is cryptic, and it immediately makes most readers balk and the remainder assume all the keys in x would have to be legal parameter names. IMHO, the fact it works is a bug in the name-checking mechanisms in the implementation. What happens when you rely on bugs? They either get fixed, or become political footballs in the PEP process. – Jon Jay Obermark Sep 01 '14 at 14:54
  • 16
    @JonJayObermark: Agree. `dict(x=2)` is ok but `dict(4=2)` is not. So if `x={4:2}` the proposed method will fail. – Miguel Apr 09 '15 at 15:42
  • 2
    `{**y, **x}` is less verbose, accepts any kinds of keys and works faster than the solution with a temporary dict. – Eugene Pakhomov Aug 14 '17 at 14:20
  • @Mechanicalsnail You say that duplicates are resolved in favor of the value in `x`. Can this idiom be slightly modified to also retain keys in `y` that are missing in `x`? Because currently they get ignored. – Ogen Sep 22 '17 at 01:26
  • does the order of `dict(y, **x)` vs `dict(**y, x)` matter? – Charlie Parker Jun 18 '18 at 17:45
  • 1
    Great answer ! There is just a small typo : "**{'a', 'x[a]'}" should be "**{'a': 'x[a]'}" i.e. replace the comma by a colon. – Ismael EL ATIFI Nov 18 '19 at 12:05
  • 3
    This answer is outdated and will sometimes fail in Python 3. Please don't waste time like I did and look at the canonical answer in the duplicate question instead: https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python – Fritz Jun 05 '20 at 09:58
  • 1
    do `{**d1, **d2}`. For details see: https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python – Charlie Parker Jul 13 '20 at 21:17
  • @Ismael ELATIFI is right, `{"a", "x[a]"}` is equivalent to `set(tuple("a", "x[a]"))` I believe. – Thomas Nov 13 '20 at 08:24
  • Oh dear now I've introduced another error, and stack overflow won't let me edit my comment anymore. It shouldn't be `tuple("a", "x[a]")`, it should just be parenthesized `("a", "x[a]")` since `tuple()` itself takes an iterable as its argument. So `{"a", "x[a]"} == set(("a", "x[a]"))`. – Thomas Nov 13 '20 at 08:36
  • why does this fail? ` self.indices_to_labels = dict(**self.labels_to_indices, **global_label2global_indices) ` – Charlie Parker Oct 27 '22 at 17:26
127

You can also use update method of dict like

a = {'a' : 0, 'b' : 1}
b = {'c' : 2}

a.update(b)
print a
Nilesh
  • 20,521
  • 16
  • 92
  • 148
64

For a static dictionary, combining snapshots of other dicts:

As of Python 3.9, the binary "or" operator | has been defined to concatenate dictionaries. (A new, concrete dictionary is eagerly created):

>>> a = {"a":1}
>>> b = {"b":2}
>>> a|b
{'a': 1, 'b': 2}

Conversely, the |= augmented assignment has been implemented to mean the same as calling the update method:

>>> a = {"a":1}
>>> a |= {"b": 2}
>>> a
{'a': 1, 'b': 2}

For details, check PEP-584

Prior to Python 3.9, the simpler way to create a new dictionary is to create a new dictionary using the "star expansion" to add teh contents of each subctionary in place:

c = {**a, **b}

For dynamic dictionary combination, working as "view" to combined, live dicts:

If you need both dicts to remain independent, and updatable, you can create a single object that queries both dictionaries in its __getitem__ method (and implement get, __contains__ and other mapping method as you need them).

A minimalist example could be like this:

class UDict(object):
   def __init__(self, d1, d2):
       self.d1, self.d2 = d1, d2
   def __getitem__(self, item):
       if item in self.d1:
           return self.d1[item]
       return self.d2[item]

And it works:

>>> a = UDict({1:1}, {2:2})
>>> a[2]
2
>>> a[1]
1
>>> a[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in __getitem__
KeyError: 3
>>> 

NB: If one wants to lazily maintain a Union "view" of two or more dictionaries, check collections.ChainMap in the standard library - as it has all dictionary methods and cover corner cases not contemplated in the example above.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • 1
    do `{**d1, **d2}`. For details see: https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python – Charlie Parker Jul 13 '20 at 21:18
  • sorry @neuron - your edit broke the answer. The second part is not **only** to older versions, it describes how to create a custom mapping which can reference independent sub-dictionaries, and this has nothing to do with the language version. (I should come back in a few minutes and fix it back, but please, watch out for the meaning of the text/code when editing) – jsbueno Sep 21 '21 at 13:37
  • why does this fail? ` self.indices_to_labels = dict(**self.labels_to_indices, **global_label2global_indices) ` – Charlie Parker Oct 27 '22 at 17:26
38

Two dictionaries

def union2(dict1, dict2):
    return dict(list(dict1.items()) + list(dict2.items()))

n dictionaries

def union(*dicts):
    return dict(itertools.chain.from_iterable(dct.items() for dct in dicts))
Mathieu Larose
  • 1,258
  • 1
  • 13
  • 15