defaultdict
defaultdict
- это структура данных из модуля collections
, которая позволяет заполнять словарь значениями по умолчанию, если ключ не был найден.
defaultdict
позволит удобно работать со словарями и избавиться от конструкций вида:
data[key] = data.get(key, 0) + 1
и
data.setdefault(key, []).append(value)
В качестве аргумента он принимает функцию-фабрику, которая вызывается, когда не был найден ключ. Результат этой функции станет значением по умолчанию.
Примеры
Словарь частот
from collections import defaultdict
text = 'Мама мыла раму'
frequency = defaultdict(int)
for symbol in text.lower():
frequency[symbol] += 1
print(*frequency.items(), sep='\n')
По умолчанию он заполнится нулями, так как в качестве фабрики мы указали int
.
>>> int()
0
('м', 4)
('а', 4)
(' ', 2)
('ы', 1)
('л', 1)
('р', 1)
('у', 1)
Без defaultdict
тело функции выглядело бы так:
if symbol in frequency:
frequency[symbol] += 1
else:
frequency[symbol] = 0
или так:
frequency[symbol] = frequency.get(symbol, 0) + 1
Инвертированный словарь частот
inv_frequency = defaultdict(list)
for letter, count in frequency.items():
inv_frequency[count].append(letter)
print(*inv_frequency.items(), sep='\n')
Здесь в качестве фабрики мы указали list
.
>>> list()
[]
(4, ['м', 'а'])
(2, [' '])
(1, ['ы', 'л', 'р', 'у'])
Без defaultdict
это выглядело бы так:
if letter in inv_frequency:
inv_frequency[count].append(letter)
else:
inv_frequency[count] = []
или так:
inv_frequency.setdefault(count, []).append(letter)
Как работает
Под капотом просто переопределяется dunder-метод __missing__
, который вызывается методом __getitem__
, если не был найден ключ.
class DefaultDict(dict):
def __missing__(self, key):
return 100
data = DefaultDict({1: 2, 3: 4})
print(data[5])
print(data.get(5))
100
None