ExampleEdit & Run

How to use defaultdicts

#import the defaultdict class from collections
from collections import defaultdict

def default_factory():
    return "Does not exist"

d = defaultdict(default_factory, Ottawa = "Canada", Helsinki = "Finland", Tokyo = "Japan")

print(d['Tokyo'])
print(d['Ottawa'])

#non-existent key
print(d['Nairobi'])
copy
Output:
Japan Canada Does not exist [Finished in 0.012329228222370148s]

A defaultdict, defined in the collections module,  is a data type that is a subclass of the standard dict type. It allows us to set, in advance, a default that will be returned whenever a non-existent key is accessed in the dictionary.

The KeyError exception is normally raised when you try to acces non-existent keys from a dictionary.

ExampleEdit & Run

non-existent keys raises KeyError exception

d = {'Ottawa': 'Canada', 'Helsinki': 'Finland', 'Tokyo': 'Japan'}

print(d['Tokyo'])
print(d['Ottawa'])
#non-existent key
print(d['Nairobi'])
copy
Output:
Japan Canada Traceback (most recent call last):   File "<string>", line 6, in <module> KeyError: 'Nairobi' [Finished in 0.009949596133083105s]

The standard dict allows us to set default values by utilizing either  the get() or the setdefault() method so that the default value is returned rather than raising the KeyError exception.

ExampleEdit & Run

Set a default value in the standard dicts

d = {'Ottawa': 'Canada', 'Helsinki': 'Finland', 'Tokyo': 'Japan'}

#set the default value when retrieving using get()
print(d.get('Delhi', 'Does not exist'))

#Set the default value for a particular key in advance using setdefault
d.setdefault('Washington', 'Does not exist')

print(d['Washington'])
copy
Output:
Does not exist Does not exist [Finished in 0.009931983891874552s]

The defaultdict, unlike the standard dict, allows us to set default value for all keys at instantiation, so that if a key(any) being accessed does not exist in the dictionary, then the default value is returned. This makes it inessential  to explicitly specify a default value for each key.

Working with defaultdicts objects

We use the following syntax to create defaultdict objects.

Syntax:
defaultdict(default_factory = None, mapping = None, iterable = None, **kwargs)
copy

Don't worry much about the syntax it is not as complicated as it seems it is literally the way we initialize standard dictionaries save for the default_factory parameter.

factory_factory This is a function that does not take any argument and should return the default value. This argument should be given as None if no default value is to be specified.
mapping Used in case where we are initializing the defaultdict with a mapping such as a standard dictionary.
iterable Used in case when we are initializing the defaultdict with an iterable containing key-value pairs.
**kwargs Used when we are initializing the defaultdict using the key = value syntax.
ExampleEdit & Run

Create a defaultdict

from collections import defaultdict

def default_factory():
    return 'Not present'

#initialize the defaultdict using an iterable
d = defaultdict(default_factory, [('one', 1), ('two', 2), ('three', 3), ('four', 4)])

print(d['one'])
print(d['three'])
print(d['four'])

print(d['five'])
copy
Output:
1 3 4 Not present [Finished in 0.011431032326072454s]

As mentioned above, you should set the default_factory argument to None, if no default value is to be specified. Note that if the default_factory is None, the KeyError exception will be raised as usual.

ExampleEdit & Run
from collections import defaultdict

d = defaultdict(None, [('one', 1), ('two', 2), ('three', 3), ('four', 4)])

print(d['one'])
print(d['three'])
print(d['four'])

print(d['five'])
copy
Output:
1 3 4 Traceback (most recent call last):   File "<string>", line 9, in <module> KeyError: 'five' [Finished in 0.0112153603695333s]

Lambda functions as default_factory functions

Since lambda functions can be defined in-line, they makes good choices for generating default values.

ExampleEdit & Run

Use lambda functions as default_factory

from collections import defaultdict

d = defaultdict(lambda : "Not present", [('one', 1), ('two', 2), ('three', 3), ('four', 4)])

print(d['one'])
print(d['three'])
print(d['four'])

print(d['five'])
copy
Output:
1 3 4 Not present [Finished in 0.011437400244176388s]

defaultdict methods

Since defaultdict class is derived from the standard dict type, it supports the same methods and operations as the dict class.

ExampleEdit & Run

Use inherited dict methods on defaultdict objects

from collections import defaultdict

d = defaultdict(lambda : "Not present", [('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5), ('six', 6), ('seven', 7)])

print(d['one'])
print(d['three'])

d['ten']

#use the get() method
print(d.get('ten', 'ten does not exist'))

#use the items() method
print(d.items())

#use the keys() method
print(d.keys())

#use the values() method
print(d.values())
copy
Output:
1 3 Not present dict_items([('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5), ('six', 6), ('seven', 7), ('ten', 'Not present')]) dict_keys(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'ten']) dict_values([1, 2, 3, 4, 5, 6, 7, 'Not present']) [Finished in 0.011490719392895699s]