Reputation: 36837
What is the best way to extend a dictionary with another one while avoiding the use of a for
loop? For instance:
>>> a = { "a" : 1, "b" : 2 }
>>> b = { "c" : 3, "d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}
Result:
{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }
Something like:
a.extend(b) # This does not work
Upvotes: 718
Views: 534150
Reputation: 1688
You can also use python's collections.ChainMap which was introduced in python 3.3.
from collections import ChainMap
c = ChainMap(a, b)
c['a'] # returns 1
This has a few possible advantages, depending on your use-case. They are explained in more detail here, but I'll give a brief overview:
This mainly makes it useful for things like configuration dictionaries.
Upvotes: 5
Reputation: 3758
Notice that since Python 3.9 a much easier syntax was introduced (Union Operators):
d1 = {'a': 1}
d2 = {'b': 2}
extended_dict = d1 | d2
>> {'a':1, 'b': 2}
Pay attention: in case first dict shared keys with second dict, position matters!
d1 = {'b': 1}
d2 = {'b': 2}
d1 | d2
>> {'b': 2}
Upvotes: 29
Reputation: 326
In terms of efficiency, it seems faster to use the unpack operation, compared with the update method.
Here an image of a test I did:
Upvotes: 2
Reputation: 89765
Have you tried using dictionary comprehension with dictionary mapping:
a = {'a': 1, 'b': 2}
b = {'c': 3, 'd': 4}
c = {**a, **b}
# c = {"a": 1, "b": 2, "c": 3, "d": 4}
Another way of doing is by Using dict(iterable, **kwarg)
c = dict(a, **b)
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
In Python 3.9 you can add two dict using union | operator
# use the merging operator |
c = a | b
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
Upvotes: 114
Reputation: 44203
a.update(b)
Latest Python Standard Library Documentation
Upvotes: 1041
Reputation: 19029
A beautiful gem in this closed question:
The "oneliner way", altering neither of the input dicts, is
basket = dict(basket_one, **basket_two)
Learn what **basket_two
(the **
) means here.
In case of conflict, the items from basket_two
will override the ones from basket_one
. As one-liners go, this is pretty readable and transparent, and I have no compunction against using it any time a dict that's a mix of two others comes in handy (any reader who has trouble understanding it will in fact be very well served by the way this prompts him or her towards learning about dict
and the **
form;-). So, for example, uses like:
x = mungesomedict(dict(adict, **anotherdict))
are reasonably frequent occurrences in my code.
Originally submitted by Alex Martelli
Note: In Python 3, this will only work if every key in basket_two is a string
.
Upvotes: 269
Reputation: 1820
As others have mentioned, a.update(b)
for some dicts a
and b
will achieve the result you've asked for in your question. However, I want to point out that many times I have seen the extend
method of mapping/set objects desire that in the syntax a.extend(b)
, a
's values should NOT be overwritten by b
's values. a.update(b)
overwrites a
's values, and so isn't a good choice for extend
.
Note that some languages call this method defaults
or inject
, as it can be thought of as a way of injecting b's values (which might be a set of default values) in to a dictionary without overwriting values that might already exist.
Of course, you could simple note that a.extend(b)
is nearly the same as b.update(a); a=b
. To remove the assignment, you could do it thus:
def extend(a,b):
"""Create a new dictionary with a's properties extended by b,
without overwriting.
>>> extend({'a':1,'b':2},{'b':3,'c':4})
{'a': 1, 'c': 4, 'b': 2}
"""
return dict(b,**a)
Thanks to Tom Leys for that smart idea using a side-effect-less dict
constructor for extend
.
Upvotes: 23
Reputation: 134721
a.update(b)
Will add keys and values from b to a, overwriting if there's already a value for a key.
Upvotes: 32