Python Counter и defaultdict: подсчёт и группировка данных
Класс Counter из модуля collections считает, сколько раз встречается каждый элемент. Класс defaultdict создаёт значение для отсутствующего ключа сам и удобен для группировки. Оба заменяют длинные циклы с проверкой if key in dict.
Подсчёт элементов через Counter
from collections import Counter
words = "кот пёс кот рыба кот пёс".split()
counts = Counter(words)
print(counts) # Counter({'кот': 3, 'пёс': 2, 'рыба': 1})
print(counts["кот"]) # 3
print(counts["слон"]) # 0
print(counts.most_common(2)) # [('кот', 3), ('пёс', 2)]
print(sum(counts.values())) # 6Для отсутствующего ключа Counter возвращает 0 и не бросает KeyError. Метод most_common(n) отдаёт n самых частых элементов.
Обновление и арифметика
counts.update(["рыба", "рыба", "слон"])
print(counts["рыба"]) # 3
print(counts["слон"]) # 1
a = Counter("aab")
b = Counter("abc")
print(a + b) # Counter({'a': 3, 'b': 2, 'c': 1})
print(a - b) # Counter({'a': 1})
print(list(counts.elements())[:3]) # ['кот', 'кот', 'кот']Группировка через defaultdict
from collections import defaultdict
people = [("Анна", "Москва"), ("Игорь", "Казань"), ("Ольга", "Москва")]
by_city = defaultdict(list)
for name, city in people:
by_city[city].append(name)
print(dict(by_city)) # {'Москва': ['Анна', 'Ольга'], 'Казань': ['Игорь']}
print(by_city["Сочи"]) # []Аргумент list это фабрика значений: при обращении к новому ключу создаётся пустой список. Обратите внимание, что чтение несуществующего ключа тоже создаёт его.
Подсчёт и суммирование через defaultdict
sales = [("хлеб", 3), ("сыр", 1), ("хлеб", 2)]
total = defaultdict(int)
for item, amount in sales:
total[item] += amount
print(dict(total)) # {'хлеб': 5, 'сыр': 1}Без collections: setdefault и get
groups = {}
for name, city in people:
groups.setdefault(city, []).append(name)
print(groups["Москва"]) # ['Анна', 'Ольга']
counts_plain = {}
for word in words:
counts_plain[word] = counts_plain.get(word, 0) + 1
print(counts_plain["кот"]) # 3Что выбрать
Задача | Инструмент |
|---|---|
Подсчитать, сколько раз встречается элемент |
|
Найти самые частые значения |
|
Сгруппировать значения по ключу |
|
Суммировать значения по ключу |
|
Группировка уже отсортированных данных |
|
Частые вопросы
Как найти самый редкий элемент в Counter?
Возьмите последние пары: counts.most_common()[-1] или min(counts, key=counts.get).
Как превратить defaultdict в обычный словарь?
Передайте его в dict(...), как в примерах выше. Так отсутствующие ключи перестанут создаваться при чтении.
Чем Counter отличается от обычного словаря?
У Counter есть арифметика (+, -), метод most_common и значение 0 для отсутствующих ключей. В остальном это подкласс dict.