ChatGPT解决这个技术问题 Extra ChatGPT

Union of dict objects in Python [duplicate]

This question already has answers here: How do I merge two dictionaries in a single expression? (43 answers) Closed 9 years ago.

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

@RikPoggi: The other question, despite its title, is asking about what the **d2 syntax is. It happens to provide an answer to this question.
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).
merged_dict = dict(**a,**b,**c,**d) worked for me too
Looks like the correct solution will come in Python 3.9, see python.org/dev/peps/pep-0584
Python 3.9 : a = {1: 'a', 2: 'b', 3: 'c'}; b = {4: 'd', 5: 'e'}; c = a | b

C
Community

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]'}

"Simple is better than complex." :) You should use update member function of dict.
How is tmp = dict(y); tmp.update(x); do_something(tmp) simpler?
@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).
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.
@JonJayObermark: Agree. dict(x=2) is ok but dict(4=2) is not. So if x={4:2} the proposed method will fail.
N
Nilesh

You can also use update method of dict like

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

a.update(b)
print a

Note that .update changes a. Sometimes, it's inacceptable
do {**d1, **d2}. For details see: stackoverflow.com/questions/38987/…
j
jsbueno

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.


do {**d1, **d2}. For details see: stackoverflow.com/questions/38987/…
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)
M
Mathieu Larose

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))

Or much more readably, dict(i for dct in dicts for i in dct.items())
Why converting to list() ? def union2(dict1, dict2): return dict(dict1.items() + dict2.items())
@kinORnirvana In python 3: a = {'x': 1}; type(a.items()) =>
@kinORnirvana "Why converting to list() ?" Because otherwise: "TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'".
do {**d1, **d2}. For details see: stackoverflow.com/questions/38987/…