Ответ
defaultdict — это подкласс стандартного словаря (dict) из модуля collections, который упрощает обработку отсутствующих ключей.
Ключевое отличие от dict: При попытке доступа к несуществующему ключу defaultdict не вызывает ошибку KeyError. Вместо этого он вызывает фабричную функцию, переданную при его создании, чтобы сгенерировать значение по умолчанию для этого ключа, после чего возвращает его.
Сравнение dict и defaultdict
Задача: подсчитать количество вхождений каждого элемента в списке.
1. С использованием обычного dict:
Требуется вручную проверять наличие ключа.
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
word_counts = {}
for word in words:
if word not in word_counts:
word_counts[word] = 0
word_counts[word] += 1
# {'apple': 3, 'banana': 2, 'orange': 1}
2. С использованием defaultdict:
Код становится чище и лаконичнее. В качестве фабричной функции используется int, которая по умолчанию возвращает 0.
from collections import defaultdict
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
# При обращении к новому ключу будет вызван int(), который вернет 0
word_counts = defaultdict(int)
for word in words:
word_counts[word] += 1
# defaultdict(<class 'int'>, {'apple': 3, 'banana': 2, 'orange': 1})
Другие примеры использования
- Группировка данных:
defaultdict(list)для сбора значений в списки.pairs = [('a', 1), ('b', 2), ('a', 3)] grouped = defaultdict(list) for key, value in pairs: grouped[key].append(value) # defaultdict(<class 'list'>, {'a': [1, 3], 'b': [2]}) - Создание вложенных словарей:
defaultdict(dict).
Ответ 18+ 🔞
Давай я тебе объясню про эту штуку, defaultdict, чтобы у тебя в голове всё встало на свои места, а не болталось, как хуй с винтом.
Представь обычный словарь, dict. Ты к нему лезешь, спрашиваешь: «Дай мне значение для ключа "банан"». А он тебе в ответ: «А такого ключа у меня нет, пошёл на хуй, получи KeyError». Знакомая история, да? Приходится каждый раз проверять: «Ой, а есть ли у тебя, сука, такой ключ? Нет? Ну тогда я его создам и значение поставлю». Пиздец как неудобно.
Вот defaultdict — это такой словарь, но с предустановленной мозгой. Ты ему заранее говоришь: «Слушай, если я приду и спрошу ключ, которого нет, — не психуй, не кидайся ошибками. Просто возьми вот эту функцию (фабрику, блядь), вызови её и сгенерируй значение по умолчанию. И сразу его мне отдай, и в себя запиши». Гениально же!
Смотри, как это работает на живом примере.
Допустим, у нас список слов, и нам надо посчитать, сколько раз каждое слово встретилось.
Стандартный способ, на обычном dict (старая школа, много писанины):
words = ['яблоко', 'банан', 'яблоко', 'апельсин', 'банан', 'яблоко']
word_counts = {}
for word in words:
if word not in word_counts: # Опа, проверяем, нет ли ключа? Ебушки-воробушки, сколько мороки!
word_counts[word] = 0
word_counts[word] += 1 # Теперь можно увеличить
# Получится: {'яблоко': 3, 'банан': 2, 'апельсин': 1}
Видишь эту вечную проверку if word not in...? Задолбать можно.
А теперь магия defaultdict (новый уровень, красиво и по-пацански):
from collections import defaultdict
words = ['яблоко', 'банан', 'яблоко', 'апельсин', 'банан', 'яблоко']
# Создаём словарь, который при встрече нового ключа вызывает int(). А int() по умолчанию возвращает 0. Красота!
word_counts = defaultdict(int)
for word in words:
word_counts[word] += 1 # Просто прибавляем! Если ключа нет — defaultdict сам создаст его со значением 0.
# defaultdict(<class 'int'>, {'яблоко': 3, 'банан': 2, 'апельсин': 1})
Никаких проверок! Ты просто говоришь «увеличь значение», а он уже сам всё понимает. Волшебство, ёпта!
И это ещё не всё, он умеет и другое!
Например, сгруппировать кучу пар в списки — задача, от которой на обычном словаре можно сойти с ума.
pairs = [('a', 1), ('b', 2), ('a', 3)]
grouped = defaultdict(list) # Говорим: новый ключ? Создавай пустой список (list())!
for key, value in pairs:
grouped[key].append(value) # Просто добавляем в список. Если списка нет — он появится сам.
# defaultdict(<class 'list'>, {'a': [1, 3], 'b': [2]})
Или сделать вложенный словарь на лету: defaultdict(dict). В общем, инструмент — огонь. Главное — передать ему правильную «фабрику» по умолчанию: int, list, dict, set или даже свою функцию.
Короче, если надоело вручную проверять ключи и инициализировать хуйню — бери defaultdict. Он тебя не подведёт, чувак.