Table of contents
The new features of the Python language since its version 3.9
are numerous and powerful. Among them is the union of dictionaries with a very simple syntax and a gain in performance.
For earlier versions of python 3.9, dictionary union is possible with the update()
function.
dict1={"John":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
dict1.update(dict2)
print(dict1)
Output:
{'John': {'Congo': ('Kinshasa', 40, 'Developer')}, 'Paul': (29, 'Designer'), 'Albert': (20, 'Developer'), 'Gerard': (30, 'Designer', 'Google')}
The problem with the update()
function is the memory. Apparently, in the previous code, the update()
function altered dict1
by adding the contents of dict2
. But in reality, internally, update()
created a copy of dict1
in memory, and added the content of dict2
to this copy. So, in the print(dict1)
line, it is this copy that is retrieved for the display of the content.
As of python 3.9, the union of dictionaries is done with a more meaningful syntax using the |
operator. It is simply a concatenation of two dictionaries as if adding two lists with an +
operator.
dict1={"John":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
united_dict = dict1 | dict2
print(united_dict)
Output:
{'John': {'Congo': ('Kinshasa', 40, 'Developer')}, 'Paul': (29, 'Designer'), 'Albert': (20, 'Developer'), 'Gerard': (30, 'Designer', 'Google')}
However, creating a new dictionary united_dict
did not solve the memory problem. The best way is to update an existing dictionary without creating a copy or a new dictionary. This is best done when you are already sure that you will not need the dictionary in its original state after updating it. Thus, the above code can be written as follows:
dict1={"John":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
dict1 |= dict2 # Means dict1 = dict1 | dict2
print(dict1)
The other advantage of the |
operator over the update()
function is that it allows more than two dictionaries to be concatenated in a single line of code. Let's add a dictionary to our code:
dict1={"John":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
dict3={"Mask":(70, "Journalist"),"Erick":(40, "Doctor") }
dict1 |= dict2 | dict3 # We can also write dict1 = dict1 | dict2 | dict3
print(dict1)
This practice can be extended to a large number of dictionaries regardless of their size.
Please note !
There is one question that must be answered before concluding this article. What happens when two dictionaries whose contents have identical keys with different values are merged ? Let's look at the exemple below.
dict1={"Albert":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
dict1 |= dict2 # We can also write dict1 = dict1 | dict2
print(dict1)
Can we guess in advance what the outcome of this code will be? dict1
contains the key "Albert"
, with another dictionary value: {"Congo":("Kinshasa", 40, "Developer" )}
. dict2
contains the same key "Albert"
, with a tuple value: (20, "Developer")
. Now, running the code, what will be the result? Let's look at the output:
{'Albert': (20, 'Developer'), 'Paul': (29, 'Designer'), 'Gerard': (30, 'Designer', 'Google')}
We see that currently, dict1
contains a single key "Albert"
whose value is the one contained in dict2
. The value of the "Albert"
key in dict1
has therefore been overwritten because a dictionary cannot contain two identical keys.
In the case where there are more than two dictionaries with identical keys, the value of the itinitial key is replaced by the value of the key of the last dictionary.
dict1={"Albert":{"Congo":("Kinshasa", 40, "Developer" )},"Paul":(29, "Designer") }
dict2={"Albert":(20, "Developer"),"Gerard":(30, "Designer", "Google") }
dict3={"Mask":(70, "Journalist"),"Albert":(40, "Doctor") }
dict4={"Grace":(50, 40, "10000USD"),"Princesse":"00000000A", "Albert":"No info given" }
dict1 |= dict2 | dict3 | dict4
print(dict1)
Output:
{'Albert': 'No info given', 'Paul': (29, 'Designer'), 'Gerard': (30, 'Designer', 'Google'), 'Mask': (70, 'Journalist'), 'Grace': (50, 40, '10000USD'), 'Princesse': '00000000A'}
Looking at this result, the key "Albert"
has the value 'No info given'
, which is the value contained in dict4
.
There are many ways to achieve dictionary union in Python. The while
or for
loops, the dict()
method, etc. can be used in some cases. In this blog post, we have tried to show the most efficient and common ways. Each method should be chosen according to the problems to be solved. I myself prefer to use the |
operator because of its performance and flexibility.