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'])

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.

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'])

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.

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'])

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.

defaultdict(default_factory = None, mapping = None, iterable = None, **kwargs)

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.

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'])

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.

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'])

Lambda functions as default_factory functions

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

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'])

defaultdict methods

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

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())