класс collections.Counter()
предназначен для удобных и быстрых подсчетов количества появлений неизменяемых элементов в последовательностях.
>>> from collections import Counter
>>> cnt = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
>>> dict(cnt)
# {'blue': 3, 'red': 2, 'green': 1}
import collections
cnt = collections.Counter([iterable-or-mapping])
iterable-or-mapping
- итерируемая последовательность или словарь.Класс Counter()
модуля collections
- это подкласс словаря dict
для подсчета хеш-объектов (неизменяемых, таких как строки, числа, кортежи и т.д.). Это коллекция, в которой элементы хранятся в виде словарных ключей, а их счетчики хранятся в виде значений словаря.
Счетчик может быть любым целочисленным значением, включая ноль или отрицательное число. Класс collections.Counter()
похож на мультимножества в других языках программирования.
Элементы считываются из итерируемой последовательности, инициализируются из другого словаря или счетчика Counter()
:
>>> from collections import Counter
# новый пустой счетчик
>>> cnt = Counter()
# новый счетчик из последовательности
>>> cnt = Counter('gallahad')
# новый счетчик из словаря
>>> cnt = Counter({'red': 4, 'blue': 2})
# новый счетчик из ключевых слов 'args'
>>> cnt = Counter(cats=4, dogs=8)
Счетчики collections.Counter()
имеют интерфейс словаря, за исключением того, что они возвращают 0 для отсутствующих элементов вместо вызова исключения KeyError
:
>>> cnt = Counter(['eggs', 'ham'])
>>> cnt['bacon']
# 0
Установка счетчика в ноль не удаляет элементы из счетчика. Используйте инструкцию del
, чтобы полностью удалить ключ счетчика:
# запись счетчика с нулевым счетом
>>> cnt['sausage'] = 0
# удаление счетчика с нулевым счетом
>>> del cnt['sausage']
Смотрите больше примеров использования класса Counter()
.
В качестве подкласса dict()
, класс Counter()
унаследовал возможность запоминания порядка вставки. Математические операции над объектами Counter()
также сохраняют порядок. Результаты упорядочены в соответствии с тем, когда элемент сначала встречается в левом операнде, а затем в порядке, в котором встречается правый операнд.
Новое в версии 3.10: Добавлены расширенные операции сравнения.
С версии Python 3.10 счетчики Counter
поддерживают расширенные операторы сравнения для отношений равенства, подмножества и надмножества: ==
, !=
, <
, <=
, >
, >=
. Все эти сравнения рассматривают отсутствующие элементы как имеющие нулевое количество, так что Counter(a=1) == Counter(a=1, b=0)
возвращает True
.
Изменено в версии 3.10: при сравнении на равенство, отсутствующие элементы рассматриваются как имеющие нулевое количество. Раньше Counter(a=3)
и Counter(a=3, b=0)
считались разными.
Counter
, атрибуты и методы:Counter.elements()
возвращает итератор по элементам.Counter.most_common()
список наиболее распространенных элементов.Counter.subtract()
вычитает элементы счетчика и итерируемой последовательности.Counter.total()
вычисляет сумму значений счетчика.Counter.update()
складывает элементы счетчика и итерируемой последовательности.Counter.elements()
:Метод Counter.elements()
возвращает итератор по элементам, в котором каждый элемент повторяется столько раз, во сколько установлено его значение. Элементы возвращаются в порядке их появления. Если количество элементов меньше единицы, то метод Counter.elements()
просто проигнорирует его.
>>> from collections import Counter
>>> cnt = Counter(a=4, b=2, c=0, d=-2)
>>> sorted(cnt.elements())
# ['a', 'a', 'a', 'a', 'b', 'b']
Counter.most_common([n])
:Метод Counter.most_common()
возвращает список из n
наиболее распространенных элементов и их количество от наиболее распространенных до наименее. Если n
опущено или None
, метод cnt.most_common()
возвращает все элементы в счетчике.
Элементы с равным количеством упорядочены в порядке, в котором они встречаются первыми:
>>> from collections import Counter
>>> Counter('abracadabra').most_common(3)
# [('a', 5), ('b', 2), ('r', 2)]
Counter.subtract([iterable-or-mapping])
:Метод Counter.subtract()
вычитает элементы текущего счетчика cnt
и итерируемой последовательности или другого словаря или другого счетчика Counter()
. Подобно методу словаря dict.update()
, но вычитает количество (значения ключей), а не заменяет их.
Значения ключей как у счетчика так и у словаря могут быть нулевыми или отрицательными.
>>> from collections import Counter
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
# Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
Counter.total()
:В Python 3.10 появился метод Counter.total()
, который вычисляет сумму значений текущего счетчика.
>>> from collections import Counter
>>> c = Counter(a=10, b=5, c=0)
>>> c.total()
# 15
В более ранних версиях Python, этот метод можно заменить выражением:
>>> from collections import Counter
>>> c = Counter(a=10, b=5, c=0)
>>> sum(c.values())
# 15
Для объектов collections.Counter()
доступны обычные методы словарей, за исключением двух, которые для счетчиков работают по-другому.
Counter.fromkeys(iterable)
:Метод Counter.fromkeys()
не реализован для объектов Counter()
.
Counter.update([iterable-or-mapping])
:Метод Counter.update()
складывает элементы текущего счетчика cnt
и итерируемой последовательности или другого словаря или другого счетчика Counter()
. Работает подобно методу словаря dict.update()
, но складывает количество (значения ключей), а не заменяет их.
Кроме того, ожидается, что итерация будет последовательностью элементов, а не последовательностью двойных кортежей (key, value)
.
>>> from collections import Counter
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.update(d)
>>> c
# Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2})
Counter()
.Общие шаблоны для работы с объектами Counter
:
>>> from collections import Counter
# создать счетчик из списка кортежей (elem, cnt)
>>> cnt = Counter(dict(list_of_pairs))
# преобразовать в список кортежей (elem, cnt)
>>> cnt.items()
# сумма всех значений в счетчике
>>> sum(cnt.values())
# очистить счетчик
>>> cnt.clear()
# список уникальных элементов
>>> list(cnt)
# преобразовать в множество
>>> set(cnt)
# преобразовать в обычный словарь
>>> dict(cnt)
# N наименее распространенных элементов
>>> cnt.most_common()[:-n-1:-1]
# Удалить элементы с нулевыми отрицательными значениями
>>> +cnt
Предусмотрено несколько математических операций для объединения объектов Counter()
для создания мультимножеств (счетчиков, число которых больше нуля). Сложение и вычитание объединяют счетчики путем сложения или вычитания количества соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих отсчетов.
Каждая операция принимает счетчики, значения ключей которых могут иметь любые числа, но выходные данные исключают из результата ключи с нулевыми отрицательными значениями.
>>> from collections import Counter
>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
# Сложить два счетчика: c[x] + d[x]
>>> c + d
# Counter({'a': 4, 'b': 3})
# Вычитание счетчиков, сохраняются
# только положительные значения элементов
>>> c - d
# Counter({'a': 2})
# Пересечение счетчиков: min(c[x], d[x])
>>> c & d
# Counter({'a': 1, 'b': 1})
# Объединение счетчиков: max(c[x], d[x])
>>> c | d
# Counter({'a': 3, 'b': 2})
Унарное сложение и вычитание являются ссылками для добавления пустого счетчика или вычитания из пустого счетчика.
>>> from collections import Counter
>>> c = Counter(a=2, b=-4)
>>> +c
# Counter({'a': 2})
>>> -c
# Counter({'b': 4})
collections.Counter()
.При помощи класса collections.Counter()
можно легко подсчитать количество повторений слов в тексте. Например найдем десять самых распространенных слов в трагедия Уильяма Шекспира "Гамлет".
from collections import Counter
from re import findall
with open('hamlet.txt') as fp:
words = findall(r'\w+', fp.read().lower())
cnt = Counter(words).most_common(10)
print(cnt)
# [('the', 1143), ('and', 966), ('to', 762),
# ('of', 669), ('i', 631), ('you', 554),
# ('a', 546), ('my', 514), ('hamlet', 471),
# ('in', 451)]
Counter()
и минимальный диапазон:Счетчики были в первую очередь предназначены для работы с положительными целыми числами для представления счетчиков.
Здесь описаны минимальный диапазон и ограничения типа Counter()
, чтобы не исключать случаи использования, требующие хранения других типов или отрицательных значений.
collections.Counter()
является подклассом словаря dict
без ограничений по ключам и значениям. Значения предназначены для чисел, представляющих счетчики, но вы можете хранить все что угодно в поле значений.cnt.most_common()
только сортирует значения ключей по убыванию.cnt[key] += 1
, тип значения должен только поддерживать сложение и вычитание. Таким образом, дроби, числа с плавающей запятой и десятичные числа будут работать, отрицательные значения то же поддерживаются. То же самое относится и к методам cnt.update()
и cnt.subtract()
, которые допускают отрицательные и нулевые значения для входных и выходных данных.Counter.elements()
работает только с положительными целыми числами и будет игнорировать ноль и отрицательные значения.