


collections.Counter считает повторения хешируемых значений и хранит результат как словарь: значение становится ключом, количество повторений становится числом. Это удобно, когда нужно получить частоты статусов, слов или кодов ошибок. Для одного заранее известного значения достаточно обычного list.count; Counter нужен, когда интересует распределение по разным значениям.
В практических разборах Mentoring.digital начнём с небольшого учебного списка. Он не связан с реальной статистикой какого-либо сервиса.
from collections import Counter
statuses = ["new", "done", "new", "error", "done", "new"]
counts = Counter(statuses)
print(dict(counts))
print(counts["cancelled"])
print(counts.most_common(2))
# {'new': 3, 'done': 2, 'error': 1}
# 0
# [('new', 3), ('done', 2)]
Обращение к отсутствующему ключу возвращает ноль. Оно само по себе не добавляет этот ключ в счётчик. Метод most_common(2) возвращает две пары «значение, количество», а не два исходных элемента. При одинаковой частоте порядок соответствует первому появлению значений.
Строки и числа подходят для ключей. Списки и словари не хешируются. Если входом служит список словарей с заявками, сначала выберите нужное поле, например Counter(row["status"] for row in rows). Такая запись требует, чтобы поле существовало; обработку отсутствующего статуса нужно определить отдельно.
counts.update(["done", "new"])
counts.update({"error": 2})
print(dict(counts))
# {'new': 4, 'done': 3, 'error': 3}
counts.subtract({"new": 4, "error": 5})
print(dict(counts))
# {'new': 0, 'done': 3, 'error': -2}
update суммирует количества. Это отличается от dict.update, который заменяет значение ключа. Переданный список означает новые наблюдения, а словарь означает уже посчитанные количества. Путать эти два формата нельзя: строка "done", переданная напрямую, будет разобрана на отдельные символы.
subtract сохраняет нулевые и отрицательные результаты. Поэтому счётчик можно использовать для разницы поступлений и списаний. Но отрицательное значение не становится доказательством ошибки: его допустимость задаёт ваша предметная задача.
left = Counter(a=2, b=1)
right = Counter(a=3, b=1)
print(dict(left - right)) # {}
left.subtract(right)
print(dict(left)) # {'a': -1, 'b': 0}
print(dict(+left)) # {}
Операция left - right создаёт новый счётчик только с положительными результатами. Метод subtract меняет существующий объект и оставляет остальные значения. Унарный плюс тоже возвращает новый счётчик без нулей и отрицательных количеств. Выбирайте операцию по смыслу данных, а не по краткости записи.
Попробуйте посчитать статусы после приведения строк через strip().lower() и сравнить результат с исходным подсчётом. Не применяйте такую нормализацию автоматически к идентификаторам, где регистр значим.
Для последовательного освоения коллекций подойдут курсы Python с практикой. Если сложность в структуре ваших данных, можно обсудить пример с наставником по Python.