Counter в Python: подсчёт значений, most_common и изменение счётчика

Counter в Python: подсчёт значений, most_common и изменение счётчика
Содержание статьи

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.

Похожие статьи по данной теме