Defaultdict in Python

Python defaultdict is a subclass of the dict class in Python's standard library. It overrides one method, __missing__, to provide a default value for a nonexistent key in the dictionary. The default value is specified as an argument when the defaultdict is created.


Syntax:
from collections import defaultdict d = defaultdict(default_value)

Here, default_value is the default value that will be returned when a key that doesn't exist in the dictionary is accessed.

Working with defaultdict

When you create a defaultdict, you specify a default factory function that is used to generate the default value for keys that haven't been set yet. The default factory function is called with no arguments and should return the default value for the dictionary.

from collections import defaultdict color_counts = defaultdict(int) # the default factory function is `int`, which returns 0 color_counts['red'] += 100 color_counts['blue'] += 200 color_counts['green'] += 300 print(color_counts)
# Output: defaultdict(<class 'int'>, {'red': 100, 'blue': 200, 'green': 300})

In the above example, create a defaultdict named color_counts with a default factory function int. This means that if you try to access a key that doesn't exist in the dictionary, the default value 0 will be returned.

Then increment the counts for 'red', 'blue', and 'green'. Since these keys didn't exist in the dictionary initially, the default factory function is called to generate the default value of 0, and then the counts are incremented accordingly.

The resulting dictionary color_counts contains the keys 'red', 'blue', and 'green', each with its corresponding count. Note that since the default factory function is int, the values associated with the keys are integers.

Following are some examples of how to use defaultdict:

Creating a defaultdict with a list:

from collections import defaultdict dd = defaultdict(list) dd['red'].append(100) dd['red'].append(200) dd['blue'].append(300) print(dd['red']) print(dd['blue'])
# Output: [100, 200] [300]

In the above example, the defaultdict is created with list as the default value. When the key 'red' is accessed, it is not yet in the dictionary, so the default value of an empty list [] is returned. Then append the values 100 and 200 to the list associated with the key 'red'. When the key 'blue' is accessed, it is also not yet in the dictionary, so the default value of an empty list [] is returned. Then append the value 300 to the list associated with the key 'blue'.

Creating a defaultdict with a lambda function:

from collections import defaultdict dd = defaultdict(lambda: 'unknown') dd['r'] = 'red' print(dd['r']) print(dd['b'])
# Output: red unknown

In the above example, the defaultdict is created with a lambda function that returns the string unknown' ' as the default value. When the key 'r' is accessed, it is not yet in the dictionary, so the lambda function is called and returns 'unknown'. Then assign the value 'red' to the key 'r'. When the key 'b' is accessed, it is also not yet in the dictionary, so the lambda function is called and returns 'unknown'.

Creating a defaultdict with a set:

from collections import defaultdict dd = defaultdict(set) dd['red'].add(100) dd['red'].add(200) dd['blue'].add(300) print(dd['red']) print(dd['blue'])
# Output: {200, 100} {300}

In the above example, the defaultdict is created with set as the default value. When the key 'red' is accessed, it is not yet in the dictionary, so the default value of an empty set {} is returned.

Dictionary Vs defaultdict

The main difference between defaultdict and a normal dictionary in Python is the way they handle missing keys.


How Does Defaultdict Work in Python

In a normal dictionary, if you try to access a key that doesn't exist in the dictionary, a KeyError is raised. You can use the get method or a try-except block to handle this error and provide a default value, but this requires extra code.

In contrast, defaultdict automatically creates a new key-value pair using a default factory function when a missing key is accessed. This can simplify your code and make it more readable.

Following is an example to illustrate the difference:

from collections import defaultdict normal_dict = {} normal_dict['red'] += 1 #Raises a KeyError # Output: KeyError: 'red' from collections import defaultdict default_dict = defaultdict(int) default_dict['red'] += 1 # Creates a new key-value pair with a default value of 0 and then increments it print(default_dict) # Output: defaultdict(<class 'int'>, {'red': 1})

In the above example, create two dictionaries - normal_dict and default_dict. Then try to increment the value associated with the key 'red' in both dictionaries, but 'red' is not yet in normal_dict, so it raises a KeyError.

In contrast, when try to increment the value associated with the key 'red' in default_dict, a new key-value pair is created with a default value of 0, and then the value is incremented to 1.

Another difference between defaultdict and a normal dictionary is that the default factory function is specified when the defaultdict is created. This means that you can use different types of default values for different defaultdict instances, whereas a normal dictionary has a fixed behavior when it comes to missing keys.

Conclusion:

Python defaultdict is a useful tool for working with dictionaries because it simplifies the code needed to handle missing keys. Rather than needing to explicitly check if a key exists in the dictionary before accessing it, you can simply use the key and let defaultdict create a default value if necessary.