Using defaultdict

Understand how to use the defaultdict with the help of multiple examples.

We’ve seen how to use the setdefault method to set a default value if a key doesn’t exist, but this can get a bit monotonous if we need to set a default value every time we look up a value. Let’s have a look at an example to better understand this concept.

Example: Count letters

For example, if we’re writing code that counts the number of times a letter occurs in a given sentence, we could do the following:

Press + to interact
from __future__ import annotations
def letter_frequency(sentence: str) -> dict[str, int]:
frequencies: dict[str, int] = {}
for letter in sentence:
frequency = frequencies.setdefault(letter, 0)
frequencies[letter] = frequency + 1
return frequencies

Every time we access the dictionary, we need to check that it already has a value; if not, set it to zero. When something like this needs to be done every time an empty key is requested, we can create a different version of a dictionary. The defaultdict, defined in the collections module, handles missing keys elegantly:

Press + to interact
from collections import defaultdict
def letter_frequency_2(sentence: str) -> defaultdict[str, int]:
frequencies: defaultdict[str, int] = defaultdict(int)
for letter in sentence:
frequencies[letter] += 1
return frequencies

This code looks odd: the defaultdict() evaluation accepts a function, int, in its constructor. We’re not evaluating the int() function; we’re providing a reference to this function to defaultdict(). Whenever a key that is not already in the dictionary is accessed, it calls that function, with no parameters, to ...