DEV Community

Michell Stuttgart
Michell Stuttgart

Posted on • Edited on

Create a dictionary from other dictionaries in Python

In this tutorial, the process of creating a dict , or dictionary, from one or more dictionaries in Python

As is customary in language, this can be done in several ways.

I recently started to practice my writing in English. I apologize in advanced for any errors. :)

Initial approach

To start, let's assume that we have the following dictionaries:

dict1 = {
    'a': 1,
    'b': 2,
}

dict2 = {
    'b': 3,
    'c': 4,
}
Enter fullscreen mode Exit fullscreen mode

As an example, let's create a new dictionary called dictx with the values of dict1 and dict2 just above. A well-known approach is to use the method update.

dictx = {}

dictx.update(dict1)
dictx.update(dict2)
Enter fullscreen mode Exit fullscreen mode

So we have to dictx will be:

print(dictx)
# output: {'a': 1,'b': 3,'c': 4}
Enter fullscreen mode Exit fullscreen mode

This method works well, but we have to call the method update for each dictionary that we want to merge in dictx. It wouldn't be interesting if it were possible to pass all dictionaries needed already at the startup of dictx?

Create a dictionary from many dicts

Python 3 introduced a very useful way to do this, using operators **.

dictx = {
 **dict1,
 **dict2,
}

print(dictx)
# output: {'a': 1,'b': 3,'c': 4}
Enter fullscreen mode Exit fullscreen mode

A real copy of dicts

When using the startup procedure above, we must have some factors in mind. Only the values of the first level will be duplicated in the new dictionary. As an example, let's change a key 'a' present in both dictionaries, and check if they have the same value:

dict1['a'] = 10
dictx['a'] = 11

print(dict1['a'])
# output: 10

print(dictx['a'])
# output: 11
Enter fullscreen mode Exit fullscreen mode

We change the reference of key 'a' in both dictionaries. However, this changes when one of the values of dict1 is a data structure, like list, another dict, or some complex object. For example:

dict3 = {
    'a': 1,
    'b': 2,
    'c': {
        'd': 5,
    },
}
Enter fullscreen mode Exit fullscreen mode

We have a dict object in key 'c'. Now, let's create a new dict from that:

dictx = {
**dict3,
}
Enter fullscreen mode Exit fullscreen mode

As in the previous example, we can imagine a copy of all the elements of dict3, however, this is not entirely true. What happened is that a copy was made superficial of the values of dict3, that is, only the values of the first level were duplicated. Take a look at what happens when we change the value of the dictionary present in the key 'c'.

dictx['c']['d'] = 11

print(dictx['c']['d'])
# output: 11

print(dict3['c']['d'])
# output: 11 (previous value was 5)
Enter fullscreen mode Exit fullscreen mode

In the case of the key 'c', it contains a reference to another data structure (a dict, in that case). When we change any value of dict3[ 'c' ], this reflects on all dictionaries that were initialized with dict3. In other words, we should pay attention when initializing a dictionary from others, when they have complex values, such as list, dict, or other objects (the attributes of this object will not be duplicated).

To get around this inconvenience, we can use the built-in Dictionary method copy. Now, when we start dictx:

dict3 = {
    'a': 1,
    'b': 2,
    'c': {
        'd': 5,
    },
}

dictx = dict3.copy()
Enter fullscreen mode Exit fullscreen mode

The method copy performs a recursive copy of each element of dict3, solving our problem. See one more example:

dictx['c']['d'] = 11

print(dictx['c']['d'])
# output: 11

print(dict3['c']['d'])
# outuput: 5 (value has not been changed)
Enter fullscreen mode Exit fullscreen mode

The values dictx and dict3 is not equal, because the 'd' of dict3['c'] and the dictx['c'] are references to distincts objects.

Conclusion

This article tries to demonstrate simply the creation of dictionaries, using some resources that the language offers and the pros and cons of each approach.

That's it.

'Thanks for reading!

Top comments (0)