The Easiest Ways to Perform Logical Operations on Two Dictionaries in Python | by Elena Kosourova | Towards Data Science

In this article, we’re going to take a look at the most straightforward ways to find the intersection, union, difference, and symmetric difference of two dictionaries in Python, both at the level of only keys and key-value pairs.
Let’s consider 2 dictionaries that have:
values of int type (so as we can use also mathematical operations),
some keys in common,
some key-value pairs in common,
other key-value pairs are specific for each dictionary.
d1 = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}d2 = {'c':3, 'd':4, 'e':50, 'f':60, 'g':7, 'h':8}
The aim here is to create a new dictionary for each of the following logical operations:
Intersection (“and”):
the same key-value pairs in both dictionaries,
the same keys in both dictionaries, with some rules applied to their corresponding values, in case the values of some keys are different in both dictionaries;
Union (“or”):
with some rules applied to the values of the keys in common, in case they are different in both dictionaries;
Difference (“not”):
taking the key-value pairs present in one of the dictionaries and absent in another (even if the same keys can be present in another dictionary with different values),
taking only the keys present in one of the dictionaries with their corresponding values;
Symmetric difference:
taking only the keys present in any of the dictionaries and absent in another, with their corresponding values.
To find the intersection of the dictionaries’ items (i.e. key-value pairs in common), we can use this short code:
inter = dict(d1.items() & d2.items())interOutput:{'d': 4, 'c': 3}
What if we’re interested in finding all the keys in common, even if the values of some of them are different in our dictionaries? We can decide to keep the values of such keys from one dictionary, say, from d1:
inter_d1 = {k:v for k,v in d1.items() if k in d2}inter_d1Output:{'c': 3, 'd': 4, 'e': 5, 'f': 6}
Or from d2:
inter_d2 = {k:v for k,v in d2.items() if k in d1}inter_d2Output:{'c': 3, 'd': 4, 'e': 50, 'f': 60}
Alternatively, we might want to take both values for each of the keys in common from both dictionaries, apply a function to them, and use the result as a value for that key in the new dictionary:
inter_max = {k:max(d1[k],d2[k]) for k in d1.keys() if k in d2}inter_min = {k:min(d1[k],d2[k]) for k in d1.keys() if k in d2}inter_sum = {k:d1[k]+d2[k] for k in d1.keys() if k in d2}print(inter_max)print(inter_min)print(inter_sum)Output:{'c': 3, 'd': 4, 'e': 50, 'f': 60}{'c': 3, 'd': 4, 'e': 5, 'f': 6}{'c': 6, 'd': 8, 'e': 55, 'f': 66}
Of course, we can use any user-defined function for these purposes:
def extraction_twice(a,b):    return (a-b)*2inter_extraction_twice = {k:extraction_twice(d2[k],d1[k]) for k in d1.keys() if k in d2}inter_extraction_twiceOutput:{'c': 0, 'd': 0, 'e': 90, 'f': 108}
Also in the case when the values are of string type:
d1_new = {1:'my', 2:'our', 3:'your'}d2_new = {1:'home', 2:'family', 4:'work'}def combine_strings(str1,str2):    return str1+ ' '+ str2inter_string = {k:combine_strings(d1_new[k],d2_new[k]) for k in d1_new.keys() if k in d2_new}inter_stringOutput:{1: 'my home', 2: 'our family'}
The code for merging two dictionaries is similar to the one we used for finding the intersection of the dictionaries’ key-value pairs, only that here we should use the merge operator:
union = dict(d1.items()|d2.items())unionOutput:{'d': 4, 'c': 3, 'h': 8, 'f': 60, 'a': 1, 'e': 50, 'g': 7, 'b': 2}
Side note: in Python 3.9, this piece of code is simplified to d1|d2.
The issue here is that the value for the key c was taken from d2, while for d — from d1. To be sure from where exactly the values are taken for the keys in common, there is a better option — the unpacking operator **:
union_d1 = {**d2, **d1}union_d1Output:{'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'a': 1, 'b': 2}
Here all the values for the keys in common were taken from d1. To take them from d2, we have to mirror the code:
union_d2 = {**d1, **d2}union_d2Output:{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 50, 'f': 60, 'g': 7, 'h': 8}
As earlier, instead of taking the values for the keys in common directly from one of the dictionaries, we might want to take both values for each such key from both dictionaries, apply a function to them (standard or user-defined), and use the result as a value for that key in the new dictionary. The approach here includes:
creating a copy of one of the dictionaries,
updating this copy based on the function to apply and on the values from another dictionary,
merging the updated copy with another dictionary.
d1_copy = d1.copy()d1_copy.update({k:max(d1[k],d2[k]) for k in d2 if d1.get(k)})union_max = {**d2, **d1_copy}union_maxOutput:{'c': 3, 'd': 4, 'e': 50, 'f': 60, 'g': 7, 'h': 8, 'a': 1, 'b': 2}
In this case, we used the max() function. However, we could use any other standard or user defined function, as we did earlier for finding the intersection.
To isolate items unique to one of the dictionaries (even if the same keys can be present in another dictionary with different values), for example, d1, we can use one of the two pieces of code below:
dif_d1 = dict(d1.items() - d2.items())dif_d1Output:{'f': 6, 'a': 1, 'e': 5, 'b': 2}
or:
dif_d1 = {k:v for k,v in d1.items() if k not in d2 or d2[k]!=v}dif_d1Output:{'a': 1, 'b': 2, 'e': 5, 'f': 6}
For d2, the code must be mirrored:
dif_d2 = dict(d2.items() - d1.items())dif_d2Output:{'h': 8, 'f': 60, 'e': 50, 'g': 7}
or:
dif_d2 = {k:v for k,v in d2.items() if k not in d1 or d1[k]!=v}dif_d2Output:{'e': 50, 'f': 60, 'g': 7, 'h': 8}
If we want to isolate the keys unique to one of the dictionaries with their corresponding values, for example, d1, we should use the following dictionary comprehension:
dif_d1_keys={k:v for k,v in d1.items() if k not in d2}dif_d1_keysOutput:{'a': 1, 'b': 2}
For d2:
dif_d2_keys={k:v for k,v in d2.items() if k not in d1}dif_d2_keysOutput:{'g': 7, 'h': 8}
Finally, to find the symmetric difference, i.e. the keys unique to both dictionaries with their corresponding values, we need:
to find the differences for both dictionaries according to the last formula,
to unite the resulting dictionaries in one.
sym_dif = {**{k:v for k,v in d1.items() if k not in d2}, **{k:v for k,v in d2.items() if k not in d1}}sym_difOutput:{'a': 1, 'b': 2, 'g': 7, 'h': 8}
To wrap up, we considered fast and comprehensive ways to perform the main logical operations on two dictionaries in Python for creating a new one. We found the intersection, union, difference, and symmetric difference of our two dictionaries both at the level of only keys and key-value pairs, sometimes using various functions for the keys in common. Certainly, these approaches are not the only ones, and you can come up with other ideas, or maybe in the future versions of Python, there will be introduced more explicit ways for these tasks. However, the pieces of code suggested are concise, elegant, and almost all of them are one-liners.
Thanks for reading!
If you liked this article, you can also find interesting the following ones: