defaultdict в Python
Что еще за defaultdict и зачем нам еще один dict? Давайте об этом и поговорим в статье.
Что такое defaultdict
Это подкласс встроенного класса dict, который вызывает фабричную функцию, позволяющую задать дефолтное значение для новых / несуществующих ключей. Во всем остальном он схож с уже знакомым нам dict.
Если упростить и вывести термин, опираясь на название, то получается, что это просто словарь с значениями по умолчанию.
Синтаксис
from collections import defaultdict defaultdict(default_factory=None, /, [...]) --> dict with default factory
Аргументы
Первый аргумент предоставляет начальное значение для атрибута default_factory, которое по умолчанию равно None. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору dict.
Пара слов про метод __missing__()
Если аргумент default_factory != None, то этот метод и вызывается для предоставления значений по умолчанию, когда запрошенный ключ не найден.
Чтобы в полной мере понять происходящее, давайте рассмотрим несколько примеров.
Примеры. Какие проблемы решает defaultdict
Получаем нужное нам значение по умолчанию
Давайте создадим 2 словаря: 1 - dict, другой - defaultdict и попробуем получить значения для существующих ключей:
from collections import defaultdict
dict_1 = {"first": 1, "second": 2}
dict_2 = defaultdict(int, first=1, second=2)
print(dict_1["first"]) # 1
print(dict_2["first"]) # 1А что, если запросить значение для несуществующего ключа:
print(dict_1["missing_key"]) # KeyError: 'missing_key' print(dict_2["missing_key"]) # 0
В первом случае мы получили исключение KeyError, а вот уже с defaultdict мы получили значение по умолчанию: 0.
Можно ли обойти эту ситуацию с помощью dict? Да, можно. Например, так:
print(dict_1.get("missing_key", 0)) # 0Здесь мы явно задали значение по умолчанию в виде 0, если не получится найти ключ.
Считаем количество слов в списке
Допустим, у нас есть список из слов list_1 и надо посчитать, сколько раз каждое слово встречается в списке, затем вывести все это в формате словаря.
Как сделать это удобно? Конечно с defaultdict!
from collections import defaultdict
list_1 = ["building", "thee", "sun", "python", "sun", "python", "python", "thee", "python"]
# 1.
result = defaultdict(int)
# 2.
for word in list_1:
result[word] += 1
# 3.
print(dict(result)) # {'building': 1, 'thee': 2, 'sun': 2, 'python': 4}
Что здесь происходит?
1. Мы инициализируем defaultdict классом int для того, чтобы для каждого нового слова было задано значение по умолчанию = 0.
2. Проходимся по всем словам из списка list_1.
- Если слово не встречалось ранее, в result создается новая пара ключ-значение, где ключ - слово, а значение - 0, после чего оно сразу увеличивается на 1.
- Если слово уже есть в словаре, то его значение просто увеличивается на 1.
3. Печатаем наш результат, предварительно преобразовав наш defaultdict в обычный dict.
В результате получаем нужный нам ответ: {'building': 1, 'thee': 2, 'sun': 2, 'python': 4}.
Делаем выводы
defaultdict в Python — это удобный инструмент для создания словарей с заданным значением по умолчанию для новых ключей. Он упрощает код, позволяя избежать явных проверок на наличие ключа перед его использованием, что делает код более чистым и сокращает необходимость в дополнительных условиях.
Это особенно полезно при работе с данными, где нужно сгруппировать или подсчитать элементы. defaultdict поддерживает различные типы значений по умолчанию, включая списки, множества и даже пользовательские функции, что делает его гибким и мощным инструментом для многих задач.