Note

Python - Default Dict - Simplify handling of missing keys in dictionaries


Overview of the Python defaultdict() function with lambdas. Avoid KeyError's in your dicts.

defaultdict(default_factory, **kwargs)is a subclass of Python standard dictionary (dict).

Python creators added several "versions" of standard dict implementation to answer some of the most common user problems.

If you call a non existent key in a standard, normal dict in Python you will get a KeyError. You can avoid this with get() method but if you would like to provide a default value for all keys that you will call in your dict, then defaultdict is a way to go.

To use defaultdict, you must import it from the collections module.

default_factory needs to be a callable (such as int, list, lambda, etc.) used to calculate the default value. It cannot accept arguments and must return the value to be used as the default.

Note: If defaultdict is initialized without a default_factory, it behaves like a regular dictionary and will raise a KeyError for missing keys.

Take a look at examples below:


from collections import defaultdict

my_dict = defaultdict(lambda: "curiosity")

print(my_dict)  # defaultdict(<function <lambda> at 0x1032ceca0>, {})

print(my_dict['dev'])  # curiosity

print(my_dict)  # defaultdict(<function <lambda> at 0x1032ceca0>, {'dev': 'curiosity'})

Output:

defaultdict(<function <lambda> at 0x1022f8ca0>, {})
curiosity
defaultdict(<function <lambda> at 0x1022f8ca0>, {'dev': 'curiosity'})

At first, our dict was empty. Then we called "dev" key, that didn't exist before and our dict returned "curiosity". And it was, of course, added to our dict.


Initializing a defaultdict with Existing Data

from collections import defaultdict

other_dict = {"starting": "value"}

my_dict = defaultdict(lambda: "curiosity", other_dict)

print(my_dict)  # defaultdict(<function <lambda> at 0x10e97d820>, {'starting': 'value'})

print(my_dict["dev"])  # curiosity

print(my_dict)  # defaultdict(<function <lambda> at 0x10e97d820>, {'starting': 'value', 'dev': 'curiosity'})

Output:

defaultdict(<function <lambda> at 0x1023c8940>, {'starting': 'value'})
curiosity
defaultdict(<function <lambda> at 0x1023c8940>, {'starting': 'value', 'dev': 'curiosity'})

We can provide additional data (here other_dict) to "prefill" my_dict.


Using defaultdict with int and lambda as Default Factories

from collections import defaultdict

my_dict = defaultdict(lambda: 0)
my_second_dict = defaultdict(int)

print(my_dict["dev"], my_second_dict["curiosity"])  # 0 0

print(my_dict)  # defaultdict(<function <lambda> at 0x10308aca0>, {'dev': 0})
print(my_second_dict)  # defaultdict(<class 'int'>, {'curiosity': 0})

Output:

0 0
defaultdict(<function <lambda> at 0x10368aca0>, {'dev': 0})
defaultdict(<class 'int'>, {'curiosity': 0})

Here both lambda: 0 and int are giving the same result.


Comparing defaultdict with Standard dict

from collections import defaultdict

my_dict = defaultdict()
my_other_dict = {}

print(my_dict == my_other_dict)  # True

my_dict = defaultdict(lambda: "curiosity")
my_other_dict = {"dev": "curiosity"}

print(my_dict == my_other_dict)  # False
print(my_dict["dev"])  # curiosity
print(my_dict == my_other_dict)  # True

Output:

True
False
curiosity
True

Comparison of defaultdict with the same keys as a "standard" dict, will result in True.


Key Points to Remember about defaultdict

  • Automatic Default Values: defaultdict returns a default value for missing keys without raising a KeyError.

  • Flexible Defaults: You can use various callables (like int, list, or lambda) for the default_factory, making defaultdict perfect for different types of defaults.

  • Comparing defaultdict and dict: Comparisons may vary depending on the keys and values, as defaultdict will dynamically add missing keys when accessed.

I hope you found this helpful! If you have any feedback, questions or requests, please reach out to me through Contact page!

Thank You Image


You might also be interested in: