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
поддерживает различные типы значений по умолчанию, включая списки, множества и даже пользовательские функции, что делает его гибким и мощным инструментом для многих задач.