Types of Dictionaries in Python

Diane Khambu
Dev Genius
Published in
4 min readJan 4, 2022

--

Photo by Jeena Paradies on Unsplash

A topic on dictionaries was something I wanted to pen down as soon as I learned about its importance, especially in Python language. Without further ado, let's make a quick tour of this omnipresent data structure.

There are 5 different types of specialized dictionaries in python. They all are present in collections module.

0. defaultdict: as the name says, we can give a default value for the currently nonexisting key.

  1. OrderedDict: keys ordering are guaranteed (based on insertion order)
  2. Counter: calculate frequency of items. The item must be able to be a key in a dictionary (hashable).
  3. ChainMap: a way to group together different dictionaries, order matters
  4. UserDict: base class to create a custom dictionary

Ok, let’s see these dictionaries in action.

A usual way to instantiate a dictionary in Python is {} or dict() . These are the special dictionaries for different use cases.

0. defaultdict

defaultdict syntax

What do you think the value of the key e would be? Let’s check the output:

defaultdict(<class 'int'>, {'a': 97, 'b': 98, 'c': 99, 'e': 0})

Look, it’s 0 . That’s because we are accessing a key that does not have a value set, hence defaultdict sets to the default value. In this case 0 . The int is callable and its default value is 0. Hence, if you do int() , it gives 0 .

Can you think of a similar scenario of setting default values in a normal dictionary?

The output is :

{'N': 1, 'a': 3, 'm': 1, 's': 1, 'k': 1, 'r': 1}

Line # 4 is basically setting the default value 0 if the value is not present. defaultdict makes having to set default value just once.

  1. OrderedDict

If an order of keys is needed, then lo and behold, Python 3.6 and above have that ready for you.

The output is:

Ordered Dict
OrderedDict([('uno', 1), ('dos', 2), ('tres', 3), ('cuatro', 4), ('cinco', 5)])
After move_to_end
OrderedDict([('dos', 2), ('tres', 3), ('cuatro', 4), ('cinco', 5), ('uno', 1)])
After move_to_end is False
OrderedDict([('uno', 1), ('dos', 2), ('tres', 3), ('cuatro', 4), ('cinco', 5)])

We also used move_to_end method to move items to the end of the dictionary or to the beginning.

Does this sound similar to some other data structure? Hello, deque . Also resides in the collections module. The corresponding deque's method of move_to_end and move_to_end with last=False are pop and popleft respectively.

2. Counter

You may have come across scenarios where you needed to calculate the frequency of items, for example calculating the frequency of words in a sentence. Python has Counter dictionary to do that job for you.

The output is:

Counter dict
Counter({'peace': 2, 'prevail': 2, 'on': 2, 'earth.': 2, 'Let': 1, 'and': 1, 'love': 1, 'May': 1})

With that magic, the Counter the dictionary has also many methods such as update , subtract with another dictionary. Check them out!

We can also use min and max function to get a key that has a minimum and maximum frequency.

3. ChainMap

You may have come across scenarios where you needed to combine a disparate collection of items. We have chain methods from itertools module to chain lists, what about dictionaries? We have ChainMap.

The output is:

ChainMap dict
ChainMap({'Daffodil': 'gradient yellow', 'Primrose': 'gradient crimson', 'Iris': 'purple'}, {'Allum': 'purple', 'Begonia': 'gradient pink', 'Delphinium': 'varied color', 'Black-Eyed-Susan': 'yellow and dark brown'}, {'Aster': 'yellow and purple', 'Dianthus': 'gradient maroon', 'Black-Eyed-Susan': 'yellow and dark brown'}, {'Crocus': 'purple', 'Snowdrop': 'white', 'Primrose': 'gradient crimson'})
change of color occurs only in first occurrence
ChainMap({'Daffodil': 'gradient yellow', 'Primrose': 'gradient crimson', 'Iris': 'purple', 'Black-Eyed-Susan': 'orange and black'}, {'Allum': 'purple', 'Begonia': 'gradient pink', 'Delphinium': 'varied color', 'Black-Eyed-Susan': 'yellow and dark brown'}, {'Aster': 'yellow and purple', 'Dianthus': 'gradient maroon', 'Black-Eyed-Susan': 'yellow and dark brown'}, {'Crocus': 'purple', 'Snowdrop': 'white', 'Primrose': 'gradient crimson'})
dictionaries in the chain maps are references to the original dictionary
flowers.maps[1] == summer_flowers => True

The order you added dictionaries to the ChainMap matters. The child is the first dictionary and the rest are the parents.

The dictionaries in the ChainMap are the reference to the original dictionaries. If you made an update to a key, only a first occurrence is updated. You can see the example with Black-Eyed-Susan the flower which occurs in both summer and autumn season gets updated only in summer_flower dictionary.

4. UserDict

There are times where you want your own custom dictionary, for example having your own set of allowed keys for the dictionary. We could subclass from a normal dict class, however, setting and getting items does not guarantee use of the dunder method __setitem__, __getitem__ . Hence, Python provides UserDict .

The output is:

SpringBouquet dict
{'Daffodil': 2, 'Glory of the Snow': 3}
setting not spring flower should raise an error
Traceback (most recent call last):
File "/Users/dichha/Documents/Projects/medium/dict/ex.py", line 93, in <module>
sb['crocus'] = 4
File "/Users/dichha/Documents/Projects/medium/dict/ex.py", line 82, in __setitem__
raise KeyError(f'Flower {key} is not a spring flower. Sorry.')
KeyError: 'Flower crocus is not a spring flower. Sorry.'

See, we made our own custom dictionary! 😍

That’s all I have for this post on dictionaries! I hope it was helpful to know about the different types of specialized dictionaries we have in Python, use them accordingly, and of course, explore more.

Thank you for reading. Happy New Year 2022! 🦋

Inspiration:

You can support me on Patreon.

--

--