Counter python: Модуль collections | Python 3 для начинающих и чайников
Модуль collections | Python 3 для начинающих и чайников
Модуль collections — предоставляет специализированные типы данных, на основе словарей, кортежей, множеств, списков.
Первым рассматриваемым типом данных будет Counter.
collections.Counter
collections.Counter — вид словаря, который позволяет нам считать количество неизменяемых объектов (в большинстве случаев, строк). Пример:
>>> import collections >>> c = collections.Counter() >>> for word in ['spam', 'egg', 'spam', 'counter', 'counter', 'counter']: ... c[word] += 1 ... >>> print(c) Counter({'counter': 3, 'spam': 2, 'egg': 1}) >>> print(c['counter']) 3 >>> print(c['collections']) 0
Но возможности Counter на этом не заканчиваются. У него есть несколько специальных методов:
elements() — возвращает список элементов в лексикографическом порядке.
>>> c = Counter(a=4, b=2, c=0, d=-2) >>> list(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b']
most_common([n]) — возвращает n наиболее часто встречающихся элементов, в порядке убывания встречаемости. Если n не указано, возвращаются все элементы.
>>> Counter('abracadabra').most_common(3) [('a', 5), ('r', 2), ('b', 2)]
subtract([iterable-or-mapping]) — вычитание
>>> c = Counter(a=4, b=2, c=0, d=-2) >>> d = Counter(a=1, b=2, c=3, d=4) >>> c.subtract(d) Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
Наиболее часто употребляемые шаблоны для работы с Counter:
- sum(c.values()) — общее количество.
- c.clear() — очистить счётчик.
- list(c) — список уникальных элементов.
- set(c) — преобразовать в множество.
- dict(c) — преобразовать в словарь.
- c.most_common()[:-n:-1] — n наименее часто встречающихся элементов.
- c += Counter() — удалить элементы, встречающиеся менее одного раза.
Counter также поддерживает сложение, вычитание, пересечение и объединение:
>>> c = Counter(a=3, b=1) >>> d = Counter(a=1, b=2) >>> c + d Counter({'a': 4, 'b': 3}) >>> c - d Counter({'a': 2}) >>> c & d Counter({'a': 1, 'b': 1}) >>> c | d Counter({'a': 3, 'b': 2})
Следующими на очереди у нас очереди (deque)
collections.deque
collections.deque(iterable, [maxlen]) — создаёт очередь из итерируемого объекта с максимальной длиной maxlen. Очереди очень похожи на списки, за исключением того, что добавлять и удалять элементы можно либо справа, либо слева.
Методы, определённые в deque:
append(x) — добавляет x в конец.
appendleft(x) — добавляет x в начало.
clear() — очищает очередь.
count(x) — количество элементов, равных x.
extend(iterable) — добавляет в конец все элементы iterable.
extendleft(iterable) — добавляет в начало все элементы iterable (начиная с последнего элемента iterable).
pop() — удаляет и возвращает последний элемент очереди.
popleft() — удаляет и возвращает первый элемент очереди.
remove(value) — удаляет первое вхождение value.
reverse() — разворачивает очередь.
rotate(n) — последовательно переносит n элементов из начала в конец (если n отрицательно, то с конца в начало).
collections.defaultdict
collections.defaultdict ничем не отличается от обычного словаря за исключением того, что по умолчанию всегда вызывается функция, возвращающая значение:
>>> import collections >>> defdict = collections.defaultdict(list) >>> print(defdict) defaultdict(<class 'list'>, {}) >>> for i in range(5): ... defdict[i].append(i) ... >>> print(defdict) defaultdict(<class 'list'>, {0: [0], 1: [1], 2: [2], 3: [3], 4: [4]})
collections.OrderedDict
collections.OrderedDict — ещё один похожий на словарь объект, но он помнит порядок, в котором ему были даны ключи. Методы:
popitem(last=True) — удаляет последний элемент если last=True, и первый, если last=False.
move_to_end(key, last=True) — добавляет ключ в конец если last=True, и в начало, если last=False.
>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
collections.namedtuple()
Класс collections.namedtuple позволяет создать тип данных, ведущий себя как кортеж, с тем дополнением, что каждому элементу присваивается имя, по которому можно в дальнейшем получать доступ:
>>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(x=1, y=2) >>> p Point(x=1, y=2) >>> p.x 1 >>> p[0] 1
Не изобретать велосипед, или Обзор модуля collections в Python
Типы данных Python не ограничиваются стандартными. Модуль collections содержит специализированные классы контейнеров, альтернативных традиционным dict
, list
и tuple
.
Это доступный «из коробки» родной модуль Python – те самые батарейки, что идут в комплекте. Уверенное владение инструментарием collections, itertools и других модулей стандартной библиотеки – одна из черт, отличающих продвинутых питонистов от новичков.
Рассмотрим на примерах самые популярные составляющие модуля collections
для Python 3 (проверено на 3.6). Для начала импортируйте библиотеку:
import collections
Одна из распространённых задач, для которой начинающие питонисты придумывают собственные решения, – подсчёт элементов последовательности: списка, строки символов и т. д.
Если нужно что-то посчитать, определить количество вхождений или наиболее (наименее) часто встречающихся элементов, используйте объекты класса Counter
. Создаются они с помощью конструктора collections.Counter()
.
Функция принимает итерируемый аргумент и возвращает словарь, в котором ключами служат индивидуальные элементы, а значениями – количества повторений элемента в переданной последовательности. Посчитаем, сколько раз встречается каждая буква в слове «абракадабра»:
>>> list_of_letters = list('абракадабра')
>>> letter_cnt = collections.Counter(list_of_letters)
>>> letter_cnt
Counter({'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1})
Обращение к ключам происходит аналогично обычному словарю:
>>> letter_cnt['а']
5
Если элемент отсутствовал в последовательности, при обращении по ключу счётчик не вызовет исключение, а вернет нулевое значение:
>>> letter_cnt['ю']
0
Присвоение нуля ключу не удаляет это значение, а создаёт соответствующую пару:
>>> letter_cnt['в'] = 0
>>> letter_cnt
Counter({'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1, 'в': 0})
Чтобы удалить пару key-value
, используем del
:
>>> del letter_cnt['в']
>>> letter_cnt
Counter({'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1})
В качестве аргумента конструктор принимает не только последовательность, но и словарь, содержащий результаты подсчёта:
>>> emotion_cnt = collections.Counter({'like':2, 'dislike':3})
>>> emotion_cnt
Counter({'like': 2, 'dislike': 3})
Метод elements()
преобразует результаты подсчета в итератор:
>>> list(emotion_cnt.elements())
['like', 'like', 'dislike', 'dislike', 'dislike']
Метод most_common(n)
ищет n
самых повторяющихся элементов. Найдём для примера три наиболее частых символа:
# без передачи аргумента выводятся все элементы
# в порядке от наиболее частых к наиболее редким
>>> letter_cnt.most_common(3)
[('а', 5), ('б', 2), ('р', 2)]
Метод возвращает список кортежей вида (ключ, число повторений)
.
Нередко интерес представляют не самые частотные, а уникальные значения, самые редкие элементы. Их можно найти срезом с шагом -1
:
>>> letter_cnt.most_common()[:-3:-1]
[('д', 1), ('к', 1)]
Счётчики складываются и вычитаются друг из друга:
>>> letter_cnt + emotion_cnt
[('д', 1), ('к', 1)]
>>> emotion_cnt - collections.Counter(like=1, dislike=3)
Counter({'like': 1})
Операнд &
даст минимальные значения для одних и тех же подсчитываемых элементов, операнд |
– максимальные:
>>> c = collections.Counter(a=4, b=2, c=0, d=-2)
>>> d = collections.Counter(a=1, b=2, c=3, d=4)
>>> c & d
Counter({'b': 2, 'a': 1})
>>> c | d
Counter({'a': 4, 'd': 4, 'c': 3, 'b': 2})
Как видно из примера, счётчику можно передавать отрицательные значения. Однако для перечисленных операций хранятся только положительные подсчеты. Нулевые или отрицательные значения обычно приходится хранить при вычитании, что реализовано в методе subtract()
:
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
Обратите внимание, что метод subtract()
обновляет сам счётчик, а не создает новый.
Распространненные шаблоны применения Counter
:
>>> sum(letter_cnt.values()) # число всех посчитанных элементов
11
>>> list(letter_cnt) # список уникальных элементов исходной последовательности
['а', 'б', 'р', 'к', 'д']
>>> set(letter_cnt)
{'а', 'б', 'д', 'к', 'р'}
>>> dict(letter_cnt) # счетчик это подкласс словаря, можно преобразовать в обычный dict
{'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1}
Унарные операции оставляют только положительные или отрицательные подcчёты:
>>> +c # способ вывести положительные подсчеты
Counter({'a': 3})
>>> -c # способ вывести отрицательные подсчеты
Counter({'c': 3, 'd': 6})
>>> c.clear() # Очищаем счетчик
>>> c
Counter()
Счетчик в сочетании с регулярными выражениями используется для частотного анализа текста. Давайте узнаем, какие десять слов чаще прочих встречаются в тексте «Евгения Онегина»:
>>> import re
>>> words = re.findall(r'\w+', open('onegin.txt').read().lower())
>>> collections.Counter(words).most_common(10)
[('и', 1011),
('в', 606),
('не', 387),
('он', 294),
('на', 260),
('с', 240),
('я', 238),
('как', 192),
('но', 190),
('что', 167)]
Что будет, если обратиться к словарю по ключу, которого в нем ещё нет?
Верно, исключение KeyError
:
>>> d = dict()
>>> d['name'] = 'James'
>>> d['surname'] = 'Bond'
>>> d['patronymic']
KeyError Traceback (most recent call last) <...>
Если нет нужды отлавливать исключение, достаточно использовать альтернативный вариант словаря – collections.defaultdict
.
Соответствующему конструктору в качестве аргумента передается тип элемента по умолчанию:
>>> d = collections.defaultdict(str)
>>> d['name'] = 'James'
>>> d['surname'] = 'Bond'
>>> d['patronymic']
''
>>> d
defaultdict(str, {'name': 'James', 'surname': 'Bond', 'patronymic': ''})
Таким образом, для ключей, к которым происходит обращение, конструктор поставит в соответствие дефолтный элемент данного типа. В случае str
– пустая строка, для целых чисел – 0
и т. д.
Обычные словари имеют метод setdefault()
, который позволяет добиться того же результата, но его использование делает программный код менее наглядным и замедляет исполнение.
Помимо str
и int
, defaultdict
часто используют в связке с пустым списком, чтобы начинать добавление элементов без лишнего кода:
>>> dict_of_lists = collections.defaultdict(list)
>>> for i in range(5):
... dict_of_lists[i].append(i)
...
>>> dict_of_lists
defaultdict(<class 'list'>, {0: [0], 1: [1], 2: [2], 3: [3], 4: [4]})
Можно видеть, что при таком подходе нет необходимости ни проверять наличие соответствующих ключей, ни создавать предварительно пустые списки.
Ощутимость пользы OrderedDict
так повлияла на обычный dict
, что в новых версиях Python различий между ними становится всё меньше. В былые времена OrderedDict
кардинально отличался от обычного словаря тем, что умел запоминать порядок вставки. Но с версии Python 3.6 на это способен и обычный словарь. Однако некоторые различия между ними все равно остаются:
- Обычный
dict
был разработан, чтобы быть лучшим в операциях, связанных с мапированием. Отслеживание порядка вставки для него – дело вторичное. И наоборот,OrderedDict
хорош в операциях переупорядочения, а эффективность, скорость итераций и производительность не главное. - Алгоритмически
OrderedDict
может обрабатывать частые операции переупорядочения лучше, чемdict.
Так как OrderedDict
это упорядоченная последовательность, объекты содержат соответствующие методы, реорганизующие структуру:
popitem(last=True)
– удаляет последний элемент еслиlast=True
, и первый, еслиlast=False
move_to_end(key, last=True)
– переносит ключkey
в конец, еслиlast=True
, и в начало, еслиlast=False
>>> d = collections.OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d.keys())
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d.keys())
'bacde'
После разговора о словарях самое время обсудить класс, умеющий объединять словари в надструктуру – ChainMap
. При этом получается не один общий словарь, а их совокупность, в которой каждый словарь остаётся независимой составляющей:
>>> letters = {'a':1, 'b':2}
>>> vowels = {'a':1, 'b':0, 'c':0, 'd': 0, 'e':1}
>>> chain = collections.ChainMap(letters, vowels)
>>> chain
ChainMap({'a': 1, 'b': 2}, {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 1})
При обращении к ChainMap
по ключу одного из словарей, происходит поиск значения среди всех словарей, при этом нет необходимости указывать конкретный словарь:
>>> chain['e']
1
При поиске ChainMap
выводит первое найденное значение (проходя словари по очереди добавления). В том числе если в словарях несколько одинаковых ключей:
>>> chain['b']
2
Изменение содержания словаря изменяет и ChainMap
. Нет необходимости перезаписывать надструктуру:
>>> letters['c'] = 3
>>> chain
ChainMap({'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 1})
Так как ChainMap
это комбинация словарей, логично, что у неё есть методы keys()
и values()
:
>>> list(chain.keys())
['c', 'd', 'a', 'e', 'b']
>>> list(chain.values())
[3, 0, 1, 1, 2]
Значения values
соответствуют списку keys
, как это было описано выше. То есть в случае несколько совпадающих ключей, выводится значение для первого из словарей, где встречается этот ключ.
При необходимости расширить составленный ранее ChainMap
можно методом new_child()
:
>>> consons = {'a':0, 'b':1, 'c':1}
>>> chain.new_child(consons)
ChainMap({'a': 0, 'b': 1, 'c': 1}, {'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 0, 'c': 0, 'd': 0, 'e': 1})
Обратите внимание, что метод не обновляет старую структуру, а создаёт новую.
Объект типа deque
(читается как «дэк», двусторонняя или двусвязная очередь) является усовершенствованным вариантом списка с оптимизированной вставкой/удалением элементов с обоих концов. Реализация deque
оптимизирована так, что операции слева и справа имеют примерно одинаковую производительность O(1)
. Добавление новых элементов в конец происходит не сильно медленнее, чем во встроенных списках, но добавление в начало выполняется существенно быстрее.
>>> seq = list("bcd")
>>> deq = collections.deque(seq)
>>> deq
deque(['b', 'c', 'd'])
>>> deq.append('e') # добавление в конец
>>> deq.appendleft('a') # добавление в начало (левый конец)
>>> deq
deque(['a', 'b', 'c', 'd', 'e'])
Чтобы добавлять не одиночный элемент, а группу итерируемого объекта iterable
используйте соответственно extend(iterable)
и extendleft(iterable
).
Аналогично методу append()
метод pop()
для deque
работает с обоих концов:
>>> deq.pop()
>>> deq.popleft()
>>> deq
deque(['b', 'c', 'd'])
Если нужно посчитать число вхождений элемента в последовательность, применяем метод count()
:
>>> deq.count('b'), deq.count('a')
(1, 0)
Кроме перечисленных, доступны следующие методы:
remove(value)
– удаление первого вхожденияvalue
reverse()
– разворачивает очередь)rotate(n=1)
– последовательно переноситn
элементов из начала в конец (еслиn
отрицательно, то с конца в начало). В этом поведениеdeque
напоминает кольцевой связный список
Очередь deque
имеет аргумент maxlen
, позволяющий ограничить ее размер. При заполнении ограниченной очереди добавление n
новых объектов «слева» вызовет удаление n
элементов справа.
Ограниченные очереди обеспечивают функциональность, похожую на tail
-фильтр в Unix:
def tail(filename, n=10):
"""Возвращает n последних строк файла'"""
with open(filename) as f:
return collections.deque(f, n)
Другой шаблон применения deque
– хранение последних добавленных элементов с выбрасыванием более старых. Пример компактной и быстрой реализации функции скользящего среднего:
import itertools
def moving_average(iterable, n=3):
# moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
it = iter(iterable)
d = collections.deque(itertools.islice(it, n-1))
d.appendleft(0)
s = sum(d)
for elem in it:
s += elem - d.popleft()
d.append(elem)
yield s / n
Алгоритм распределения нагрузки Round-robin можно реализовать с помощью итераторов, хранящихся в deque
. Значения выводятся из активного итератора в нулевой позиции. Если этот итератор исчерпан, его можно удалить методом popleft ()
; в противном случае его можно циклически «провернуть» до конца методом rotate()
:
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
iterators = collections.deque(map(iter, iterables))
while iterators:
try:
while True:
yield next(iterators[0])
iterators.rotate(-1)
except StopIteration:
# Удалить "закончившийся" итератор
iterators.popleft()
namedtuple()
– функция-фабрика для создания именованных кортежей. Этот тип данных похож на struct
в других языках программирования:
>>> cols = ['fname', 'pname', 'lname', 'age']
>>> User = collections.namedtuple('User', cols)
>>> user1 = User('Петр', 'Иванович', 'Сидоров', 30)
>>> user1
User(fname='Петр', pname='Иванович', lname='Сидоров', age=30)
>>> user1.lname
Сидоров
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(3, 4)
>>> p.x**2 + p.y**2
25
Именованные кортежи делают код яснее – вместо индексирования составляющие объекта вызываются по явным именам. Остаётся доступной и численная индексация:
>>> p[0]**2 + p[1]**2
25
Именованные кортежи часто используются для назначения имён полей кортежам, возвращаемым модулями csv
или sqlite3
:
EmployeeRecord = collections.namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
print(emp.name, emp.title)
import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
print(emp.name, emp.title)
Структура namedtuple
похожа на словарь. Посредством метода _asdict
можно представить те же данные в виде OrderedDict
:
>>> p._asdict()
OrderedDict([('x', 3), ('y', 4)])
Чтобы вызвать значение через строковый ключ, необязательно преобразовывать namedtuple
– подходит стандартная функция getattr()
:
>>> getattr(p, 'x')
3
Чтобы преобразовать словарь в именованный кортеж заданного типа, достаточно распаковать его оператором **
:
>>> d = {'x': 0, 'y': 1}
>>> Point(**d)
Point(x=0, y=1)
Имена полей namedtuple
перечислены в _fields
:
>>> user1._fields, p._fields
(('fname', 'pname', 'lname', 'age'), ('x', 'y'))
С версии 3.7 можно присвоить полям значения по умолчанию.
Поскольку именованный кортеж является обычным классом Python, в него легко привнести новую функциональность или изменить старую. Например, добавим к Point
расчёт гипотенузы и формат вывода данных:
class Point(collections.namedtuple('Point', ['x', 'y'])):
__slots__ = () # предотвращает создание словарей экземпляров
@property
def hypot(self):
return (self.x**2 + self.y**2) ** 0.5
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
for p in Point(3, 4), Point(14, 5/7):
print(p)
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 0.714 hypot=14.018
Если вам пришлась по душе компактность namedtuple
в сравнении с обычными классами и ваш проект может работать с версиями Python не меньше 3.7, присмотритесь к модулю dataclasses. Эта встроенная библиотека предоставляет декоратор и функции для автоматического добавления в пользовательские классы сгенерированных специальных методов, таких как __init__()
и __repr__()
.
Подведём итог нашему рассказу об основных составляющих модуля collections:
- Counter – инструмент подсчёта неизменяемых объектов. Используйте, если нужно определить количество вхождений или число наиболее (наименее) часто встречающихся элементов.
- defaultdict – словарь, умеющий при вызове отсутствующего ключа вместо вызова исключения
KeyError
записывать значение по умолчанию (работает быстрее, чем методsetdefault()
). - OrderedDict – словарь с памятью порядка добавления элементов, умеющий переупорядочивать элементы лучше, чем
dict
. - ChainMap – контейнер комбинаций словарей с поиском, обобщением ключей и элементов.
- namedtuple() – функция-фабрика для создания именованного кортежа. Это один из простейших способов сделать код более ясным: использовать вместо индексов имена.
- deque – двусторонняя очередь – список, оптимизированный для вставки и удаления элементов с обоих концов с методом подсчёта вхождений
- UserDict, UserList, UserString – не заслуживающие развёрнутого описания обертки над стандартными объектами словарей, списков и строк для беспроблемного наследования (прямое наследование встроенным типам
dict
,list
,str
чревато ошибками, связанными с игнорированием переопределения методов).
Также у модуля collections имеется наследованный модуль коллекции абстрактных базовых классов сollections.abc
. Но это тема отдельного разговора.
Операции с Python Counter | Портал информатики для гиков
Счетчик может использоваться для вычисления частоты в списке или в строке, поскольку, поскольку любой список или строка передается в качестве входных данных, он возвращает выходные данные в виде словаря, ключи которого являются уникальными элементами списка, а значения — соответствующими частотами элементы.
В приведенном ниже коде счетчик из библиотеки Python коллекции импортируется, чтобы найти частоту каждого уникального символа, встречающегося в этой строке. Используя счетчик в списке, можно также найти частоту каждого уникального элемента, присутствующего в списке.
|
Выход:
c1 : Counter({'b': 3, 'c': 3, 'a': 2, 'f': 2, 'e': 1, 'd': 1}) t1 : Counter({1: 3, 4: 3, 0: 2, 3: 2, 6: 2, 2: 1, 5: 1})
Выполнение определенных операций с возвращенным выходным словарем, если d является выходным словарем, например d.items (), d.keys (), d.values ()
|
Выход:
d : Counter({'b': 3, 'c': 3, 'a': 2, 'f': 2, 'e': 1, 'd': 1}) d.values() : dict_values([2, 3, 3, 2, 1, 1]) d.items() : dict_items([('a', 2), ('b', 3), ('c', 3), ('f', 2), ('e', 1), ('d', 1)]) d.keys() : dict_keys(['a', 'b', 'c', 'f', 'e', 'd']) sorted(d) : ['a', 'b', 'c', 'd', 'e', 'f']
Добавление двух счетчиков
Сложение двух счетчиков создает сложения значений, соответствующие каждому ключу, и если ключ присутствует в одном счетчике, а не в другом, то в этом случае это значение ключа также попадает в окончательный вывод.
|
Выход:
t1: Counter({'g': 2, 'a': 2, 'b': 2, 'f': 2, 'd': 2, 'k': 1, 'j': 1, 'i': 1}) t2: Counter({'a': 3, 'b': 3, 'h': 3, 's': 3, 'l': 2, 'g': 2, 'k': 2, 'd': 1}) t1+t2 : Counter({'a': 5, 'b': 5, 'g': 4, 'k': 3, 'h': 3, 'd': 3, 's': 3, 'l': 2, 'f': 2, 'j': 1, 'i': 1})
Вычитание двух счетчиков
Количество общих элементов вычитается друг из друга и (сохраняет только положительные значения)
|
Выход:
t1: Counter({'f': 2, 'd': 2, 'b': 2, 'a': 2, 'g': 2, 'k': 1, 'i': 1, 'j': 1}) t2: Counter({'h': 3, 'b': 3, 'a': 3, 's': 3, 'l': 2, 'k': 2, 'g': 2, 'd': 1}) t1-t2 : Counter({'f': 2, 'i': 1, 'j': 1, 'd': 1}) t2-t1 : Counter({'h': 3, 's': 3, 'l': 2, 'k': 1, 'b': 1, 'a': 1})
Пересечения (&) двух счетчиков
Intersaction (&) сохранит только минимум соответствующих отсчетов: min (t1 [x], t2 [x]):
|
Выход:
t1 : Counter({'e': 4, 'b': 4, 'a': 3, 'c': 2, 'd': 1}) t2 : Counter({'c': 4, 'd': 3, 'a': 2, 'e': 2, 'b': 2}) t1&t2 : Counter({'c': 2, 'a': 2, 'e': 2, 'b': 2, 'd': 1})
Союз (|) двух счетчиков
Union (|) сохранит только максимум соответствующих отсчетов: max (c [x], d [x]):
|
Выход:
t1 : Counter({'b': 4, 'e': 4, 'a': 3, 'c': 2, 'd': 1}) t2 : Counter({'c': 4, 'd': 3, 'a': 2, 'b': 2, 'e': 2}) t1|t2 : Counter({'b': 4, 'e': 4, 'c': 4, 'a': 3, 'd': 3})
Рекомендуемые посты:
Операции с Python Counter
0.00 (0%) 0 votes
Стандартная библиотека Python — для обработки языка: collections.Counter
Сегодня я хотел бы рассказать об одном интересном классе стандартной библиотеки языка Python, который может пригодиться при обработке языка. Речь пойдет о классе Counter из библиотеки collections.
Кратко
Counter – очень полезная вещь при частотном анализе текста.
Отдавая на вход список слов (который list), получаем объект класса Counter, очень похожий на словарь (который dictionary).
Импортируем класс
from collections import Counter
Простейший пример:
from collections import Counter data = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] #создаём объект класса Counter и передаем ему список в качестве аргумента cntr = Counter(data) print cntr Out: Counter({'vista': 2, 'la': 2, 'hasta': 1, 'baby': 1})
Итак, имелся некий список слов произвольной длины, мы создали объект класса Counter и передали ему на вход в качестве единственного аргумента этот список. На выходе получили словарь (а на самом деле объект класса Counter), где ключ — это слово из списка, а значение — количество раз, когда слово встретилось.
В дальнейшем «объект класса Counter» для простоты будем называть просто «каунтер», и да простит меня Розенталь.
Базовые возможности
Доступ к элементам там такой же, как и у словаря: то есть, обращаясь по ключу — получаем значение. Если вдруг обратимся к ключу, которого по недоразумению нет в каунтере, то на выходе получим 0, а не ошибку, что приятно. Добавление и удаление элементов в каунтере такое же, как в словаре.
from collections import Counter data = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] cntr = Counter(data) print cntr Out: Counter({'vista': 2, 'la': 2, 'hasta': 1, 'baby': 1}) #обращаемся к существующему элементу print cntr['hasta'] Out: 1 #обращаемся к несуществующему элементу print cntr['pasta'] Out: 0 #добавляем новый элемент cntr['pasta'] = 2 print cntr Out: Counter({'vista': 2, 'pasta': 2, 'la': 2, 'hasta': 1, 'baby': 1}) #удаляем элемент del cntr['pasta'] print cntr Out: Counter({'vista': 2, 'la': 2, 'hasta': 1, 'baby': 1})
Методы
Метод Counter.most_common() дает на выходе наиболее частотные элементы из каунтера, главное — указать сколько именно нужно наиболее частотных элементов. Однако, если очень захотеть, то можно получить и наименее частотные документы.
Не стоит забывать, что на выходе этого метода получается список кортежей, где в каждом кортеже первый элемент — это ключ, а второй — значение.
from collections import Counter data = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] cntr = Counter(data) #выводим на экран два самых частотных элемента print cntr.most_common(2) Out: [('vista', 2), ('la', 2)] #выводим на экран два самых редких элемента #цифра 2 в [:-2-1:-1] означает число элементов, #которое нам нужно print cntr.most_common()[:-2-1:-1] Out: [('baby', 1), ('hasta', 1)]
С помощью метода Counter.elements() можно получить список элементов в зависимости от их количества. А применяя метод Counter.values() — список всех значений:
from collections import Counter data = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] cntr = Counter(data) #выводим список всех ключей print list(cntr.elements()) Out: ['hasta', 'baby', 'vista', 'vista', 'la', 'la'] #выводим список всех значений print cntr.values() Out: [1, 1, 2, 2, 2]
Метод Counter.subtract() выдает разность значений для одинаковых ключей в двух объектах типа Counter. То есть, если у нас есть два каунтера cодинаковыми ключами и разными значениями, то, применяя метод Counter.subtract() мы вычитаем значение ключа одного каунтера из другого, при этом отрицательное значение в итоге — допустимо. А если ключи в каунтерах разные, то при вычитании одного каунтера из другого считаем, что несуществующий ключ на самом деле существует, просто его значение — 0. Я думаю, на примере это выглядит более понятно:
from collections import Counter #вариант 1 cntr1 = Counter({'hasta': 8}) cntr2 = Counter({'hasta': 5}) #Вычитаем cntr2 из cntr1 cntr1.subtract(cntr2) print cntr1 Out: Counter({'hasta': 3}) #Вычитаем cntr1 из cntr2 cntr2.subtract(cntr1) print cntr2 Out: Counter({'hasta': -3}) #Вариант2 cntr1 = Counter({'hasta': 8}) cntr2 = Counter({'vista': 5}) #Вычитаем cntr2 из cntr1 cntr1.subtract(cntr2) print cntr1 Out: Counter({'hasta': 8, 'vista': -5}) #Вычитаем cntr1 из cntr2 cntr2.subtract(cntr1) print cntr2 Out: Counter({'vista': 5, 'hasta': -8})
Если нам не нравится наличие отрицательных или нулевых значений после операции вычитания методом Counter.subtract(), то можно их убрать довольно нехитрым способом — прибавления к имеющемуся каунтеру пустого каунтера:
from collections import Counter #убираем элементы с отрицательными значениями cntr = Counter({'hasta': 5, 'vista': -8}) cntr += Counter() print cntr Out: Counter({'hasta': 5})
Преобразование каунтера
С помощью метода Counter.items() можно преобразовать каунтер в список, а все связки ключ-значение — в кортежи, так что на выходе мы получаем список кортежей, где первым элементом становится бывший ключ, а вторым не менее бывшее значение.
Стандартный метод dict() действует ожидаемо — каунтер становится обычным словарём без каких-либо выдающихся методов, вроде most_common.
А вот set() и list() дают на выходе множество и список ключей соответственно — в принципе, точки зрения данных — одно и то же.
from collections import Counter data = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] cntr = Counter(data) #преобразуем в список кортежей print cntr.items() Out: [('hasta', 1), ('baby', 1), ('vista', 2), ('la', 2)] #преобразуем в словарь print dict(cntr) Out: {'hasta': 1, 'baby': 1, 'vista': 2, 'la': 2} #преобразуем в список print list(cntr) Out: ['hasta', 'baby', 'vista', 'la'] #преобразуем во множество print set(cntr) Out: set(['hasta', 'baby', 'vista', 'la'])
Операции с каунтерами
А еще между каунтерами можно проводить арифметические и действия — сложение, когда значения ключей складываются и вычитание, которое отличается от метода subtract тем, что в итоговом каунтере остаются только положительные значения. Никаких нулей либо отрицательных чисел, даже не просите!
from collections import Counter cntr1 = Counter({'hasta': 4, 'vista': 1}) cntr2 = Counter({'hasta': 1, 'vista': 2}) #складываем print cntr1 + cntr2 Out: Counter({'hasta': 5, 'vista': 3}) #вычитаем print cntr1 - cntr2 Out: Counter({'hasta': 3})
А еще можно проводить те же операции, что и с множествами — пересечение и объединение. В чём их особенность?
Пересечение двух каунтеров даёт каунтер, где присутствуют только ключи, которые есть в обоих каунтерах с минимальным значением среди этих ключей. Т.е. если в одном каунтере есть связка ‘vista’: 4, а в другом — ‘vista’: 3, то в результате пересечения получим ‘vista’: 3. При этом, само собой, если пересекающихся ключей нет, то в результате получим пустой каунтер.
При объединении мы получаем те связки ключ-значение, которые есть либо в одном, либо в другом каунтере (что очевидно). Если оказываются пересекающиеся ключи, то предпочтение отдается ключу с максимальным значением. То есть, если в одном каунтере есть связка ‘vista’: 4, а в другом — ‘vista’: 3, то в результате пересечения получим ‘vista’: 4.
Само собой, пример нагляднее:
from collections import Counter cntr1 = Counter({'hasta': 4, 'vista': 1, 'pasta': 7}) cntr2 = Counter({'hasta': 1, 'vista': 2}) #Проводим пересечение print cntr1 & cntr2 Out: Counter({'hasta': 1, 'vista': 1}) #Проводим объединение print cntr1 | cntr2 Out: Counter({'pasta': 7, 'hasta': 4, 'vista': 2})
Практическое применение
Каково же практическое применение данного класса для задач обработки естественного языка?
С ходу в голову приходят такие идеи:
- Частотный анализ текстов
- Анализ наиболее/наименее частотных слов в тексте либо в корпусе текстов конкретного автора
- Сравнение наиболее/наименее частотной лексики у разных авторов или в разных областях знаний
- Использование при расчёте TF-IDF (Term Frequency — Inverse Document Frequency). TF для каждого слова рассчитывается как количество раз, когда слово встретилось в тексте, деленное на общее количество слов в тексте. Вот как-то так, например:
def compute_tf(text): #преобразуем входной список в каунтер tf_text = Counter(text) #используем генератор словарей для деления значения каждого элемента #в каунтере на общее число слов в тексте - т.е. длину списка слов. tf_text = {i: tf_text[i]/float(len(text)) for i in tf_text} return tf_text text = ['hasta', 'la', 'vista', 'baby', 'la', 'vista'] print compute_tf(text) Out: {'hasta': 0.166666666667, 'baby': 0.166666666667, 'vista': 0.333333333333, 'la': 0.333333333333}
Полезные ссылки
Описание Counter в стандартной документации Python 2.7 (англ.)
Описание Counter в переводе стандартной документации для Python 3 (рус.)
Википедия о TF-IDF (рус.)
13,947 просмотров всего, 10 просмотров сегодня
Стандартная библиотека Python — для обработки языка: collections.Counter
5 1 vote
Python Language — collections.Counter | python Tutorial
пример
Счетчик — это подкласс класса dict, который позволяет легко подсчитывать объекты. Он имеет полезные методы для работы с частотами объектов, которые вы считаете.
import collections
counts = collections.Counter([1,2,3])
приведенный выше код создает объект, счетчик, который имеет частоты всех элементов, переданных конструктору. Этот пример имеет значение Counter({1: 1, 2: 1, 3: 1})
Примеры конструктора
Счетчик писем
>>> collections.Counter('Happy Birthday')
Counter({'a': 2, 'p': 2, 'y': 2, 'i': 1, 'r': 1, 'B': 1, ' ': 1, 'H': 1, 'd': 1, 'h': 1, 't': 1})
Счетчик слов
>>> collections.Counter('I am Sam Sam I am That Sam-I-am That Sam-I-am! I do not like that Sam-I-am'.split())
Counter({'I': 3, 'Sam': 2, 'Sam-I-am': 2, 'That': 2, 'am': 2, 'do': 1, 'Sam-I-am!': 1, 'that': 1, 'not': 1, 'like': 1})
Рецепты
>>> c = collections.Counter({'a': 4, 'b': 2, 'c': -2, 'd': 0})
Получить количество отдельных элементов
>>> c['a']
4
Установить количество отдельных элементов
>>> c['c'] = -3
>>> c
Counter({'a': 4, 'b': 2, 'd': 0, 'c': -3})
Получить общее количество элементов в счетчике (4 + 2 + 0 — 3)
>>> sum(c.itervalues()) # negative numbers are counted!
3
Получить элементы (сохраняются только те, у которых есть положительный счетчик)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
Удалить ключи с 0 или отрицательным значением
>>> c - collections.Counter()
Counter({'a': 4, 'b': 2})
Удалить все
>>> c.clear()
>>> c
Counter()
Добавить удалить отдельные элементы
>>> c.update({'a': 3, 'b':3})
>>> c.update({'a': 2, 'c':2}) # adds to existing, sets if they don't exist
>>> c
Counter({'a': 5, 'b': 3, 'c': 2})
>>> c.subtract({'a': 3, 'b': 3, 'c': 3}) # subtracts (negative values are allowed)
>>> c
Counter({'a': 2, 'b': 0, 'c': -1})
Коллекции
— Типы данных контейнеров — документация Python 3.8.6
Исходный код: Lib / collections / __ init__.py
Этот модуль реализует специализированные типы данных контейнера, предоставляя альтернативы
Встроенные контейнеры общего назначения Python, dict
, list
,
устанавливает
, а кортеж -
.
| фабричная функция для создания подклассов кортежей с именованными полями |
| контейнер в виде списка с быстрым добавлением и всплывающим окном на обоих концах |
| dict-подобный класс для создания единого представления нескольких сопоставлений |
| подкласс dict для подсчета хешируемых объектов |
| подкласс dict, который запоминает добавленные записи заказа |
| подкласс dict, который вызывает заводскую функцию для предоставления отсутствующих значений |
| Обертка вокруг словарных объектов для упрощения подкласса dict |
| оболочка вокруг объектов списка для упрощения создания подклассов списка |
| оболочка вокруг строковых объектов для упрощения создания подклассов строк |
Класс ChainMap
предназначен для быстрого связывания нескольких отображений.
поэтому их можно рассматривать как единое целое.Часто это намного быстрее, чем создавать
новый словарь и выполнение нескольких вызовов update ()
.
Класс может использоваться для моделирования вложенных областей видимости и полезен при создании шаблонов.
- класс
коллекций.
ChainMap
( * карты ) A
ChainMap
группирует несколько dicts или других отображений вместе в
создать единое обновляемое представление. Если не указаны карты , будет один пустой
словарь предоставляется, так что новая цепочка всегда имеет хотя бы одно отображение.Базовые сопоставления хранятся в списке. Этот список является общедоступным и может
можно получить доступ или обновить с помощью атрибута maps . Нет другого государства.Поисковые запросы последовательно ищут базовые сопоставления, пока не будет найден ключ. В
Напротив, записи, обновления и удаления работают только с первым отображением.ChainMap
включает базовые сопоставления посредством ссылки. Так что если
обновляется одно из базовых сопоставлений, эти изменения будут отражены
вChainMap
.Поддерживаются все обычные словарные методы. Кроме того, есть
отображает атрибут , метод для создания новых подконтекстов и свойство для
доступ ко всем, кроме первого сопоставления:-
карт
Список отображений, обновляемый пользователем. Список заказан из
от первого до последнего. Это единственное сохраненное состояние и может
можно изменить, чтобы изменить поиск сопоставлений. Список должен
всегда содержать хотя бы одно отображение.
-
new_child
( m = нет ) Возвращает новую
ChainMap
, содержащую новую карту, за которой следует
все карты в текущем экземпляре. Если указаном
,
она становится новой картой в начале списка сопоставлений; если не
указан пустой dict, так что вызовd.new_child ()
эквивалентно:ChainMap ({}, * d.maps)
. Этот метод используется для
создание подконтекстов, которые можно обновлять без изменения значений в любых
родительских отображений.Изменено в версии 3.4: добавлен дополнительный параметр
м
.
-
родителей
Свойство возвращает новую
ChainMap
, содержащую все карты в
текущий экземпляр, кроме первого. Это полезно для пропуска
первая карта в поиске. Сценарии использования аналогичны тем, которые используются для
нелокальное ключевое слово
, используемое во вложенных областях. Варианты использования также совпадают с вариантами использования встроенного
super ()
функция.Ссылка наd.parents
эквивалентна:
ChainMap (* d.maps [1:])
.
Обратите внимание, порядок итерации
ChainMap ()
определяется
сканирование сопоставлений от последнего к первому:>>> baseline = {'music': 'bach', 'art': 'rembrandt'} >>> Adjustments = {'art': 'van gogh', 'opera': 'carmen'} >>> список (ChainMap (корректировки, базовый уровень)) ['музыка', 'искусство', 'опера']
Это дает тот же порядок, что и серия
dict.update ()
звонков
начиная с последнего сопоставления:>>> комбинированный = baseline.copy () >>> Combined.update (корректировки) >>> список (объединенный) ['музыка', 'искусство', 'опера']
-
ChainMap
Примеры и рецепты
В этом разделе показаны различные подходы к работе с связанными картами.
Пример моделирования внутренней поисковой цепочки Python:
встроенных импорта pylookup = ChainMap (locals (), globals (), vars (встроенные))
Пример разрешения аргументам командной строки, заданным пользователем, иметь приоритет над
переменные среды, которые, в свою очередь, имеют приоритет над значениями по умолчанию:
.
Python Counter в коллекциях с примером
- Home
Testing
- Back
- Agile Testing
- BugZilla
- Cucumber
- Database Testing
- 9000 J27 9000 J27
- 9000 J27
- JUnit
- LoadRunner
- Ручное тестирование
- Мобильное тестирование
- Mantis
- Почтальон
- QTP
- Назад
- Центр качества (ALM)
- 000
- Центр качества (ALM)
000 Управление тестированием
- TestLink
SAP
- Назад
- ABAP
- APO
- Начинающий
- Basis
- BODS
- BI
- BPC
- CO
- Назад
- CRM
- Crystal Reports
- QM4000
- QM4
- Заработная плата
- Назад
- PI / PO
- PP
- SD
- SAPUI5
- Безопасность
- Менеджер решений
- Successfactors
- Учебники SAP
- Apache
- Назад
- Java
- JSP
- Kotlin
- Linux
- Linux
- Kotlin
- Linux
- Perl
js
- Назад
- PHP
- PL / SQL
- PostgreSQL
- Python
- ReactJS
- Ruby & Rails
- Scala
- SQL
- SQL
- UML
- VB.Net
- VBScript
- Веб-службы
- WPF
000
000
0003 SQL
000
0003 SQL
000
Обязательно учите!
- Назад
- Бухгалтерский учет
- Алгоритмы
- Android
- Блокчейн
- Business Analyst
- Создание веб-сайта
- CCNA
- Облачные вычисления
- 0003 COBOL
- 000 Compiler
- 9000 Встроенный
- 000 9000 Compiler
- Ethical Hacking
- Учебники по Excel
- Программирование на Go
- IoT
- ITIL
- Jenkins
- MIS
- Сети
- Операционная система
- 0003
- Назад
- Управление проектами
.
Python Counter — Python Collections Counter
Python Counter Class является частью модуля Collections. Counter — это подкласс Dictionary, используемый для отслеживания элементов и их количества.
Python Counter
Counter — это неупорядоченная коллекция, в которой элементы хранятся как ключи Dict
, а их количество — как значение dict.
Количество элементов счетчика может быть положительным, нулевым или отрицательным целым числом. Однако никаких ограничений на ключи и значения нет. Хотя значения предназначены быть числами, мы можем хранить и другие объекты.
Создание объекта счетчика Python
Мы можем создать пустой счетчик или начать с некоторых начальных значений.
из коллекций счетчик импорта
# пустой счетчик
counter = Счетчик ()
print (counter) # Counter ()
# Счетчик с начальными значениями
counter = Counter (['a', 'a', 'b'])
print (counter) # Counter ({'a': 2, 'b': 1})
counter = Counter (a = 2, b = 3, c = 1)
print (counter) # Counter ({'b': 3, 'a': 2, 'c': 1})
Мы также можем использовать любой Iterable в качестве аргумента для создания объекта Counter.Таким образом, строковый литерал и список также могут использоваться для создания объекта Counter.
# Итерируемый как аргумент для Counter
counter = Счетчик ('abc')
print (counter) # Counter ({'a': 1, 'b': 1, 'c': 1})
# Список в качестве аргумента Counter
words_list = ['Кошка', 'Собака', 'Лошадь', 'Собака']
counter = Счетчик (список_слов)
print (counter) # Counter ({'Dog': 2, 'Cat': 1, 'Horse': 1})
# Словарь как аргумент счетчика
word_count_dict = {'Собака': 2, 'Кошка': 1, 'Лошадь': 1}
counter = Счетчик (word_count_dict)
print (counter) # Counter ({'Dog': 2, 'Cat': 1, 'Horse': 1})
Как я упоминал выше, мы также можем использовать нечисловые данные для значений счетчика, но это нарушит назначение класса Counter.
# Счетчик работает и с не числами
special_counter = Counter (name = 'Pankaj', возраст = 20)
print (special_counter) # Счетчик ({'name': 'Pankaj', 'age': 20})
Методы счетчика Python
Давайте рассмотрим методы класса Counter и некоторые другие операции, которые мы можем выполнять с ним.
Подсчет элементов
# подсчет
counter = Counter ({'Собака': 2, 'Кошка': 1, 'Лошадь': 1})
countDog = counter ['Собака']
печать (countDog) # 2
Если мы попытаемся получить количество несуществующего ключа, он вернет 0 и не выдаст KeyError
.
# получение счетчика для несуществующего ключа, не вызывает KeyError
print (counter ['Unicorn']) # 0
Установка количества элементов
Мы также можем установить количество существующих элементов в счетчике. Если элемент не существует, он добавляется в счетчик.
counter = Counter ({'Собака': 2, 'Кошка': 1, 'Лошадь': 1})
# установка счетчика
counter ['Horse'] = 0
print (counter) # Counter ({'Dog': 2, 'Cat': 1, 'Horse': 0})
# установка счетчика для несуществующего ключа, добавляет в счетчик
counter ['Unicorn'] = 1
print (counter) # Counter ({'Dog': 2, 'Cat': 1, 'Unicorn': 1, 'Horse': 0})
Удаление элемента из счетчика
Мы можем использовать del
для удаления элемента из объекта счетчика.
# Удалить элемент из счетчика
del counter ['Единорог']
print (counter) # Counter ({'Dog': 2, 'Cat': 1, 'Horse': 0})
elements ()
Этот метод возвращает список элементов в счетчике. Возвращаются только элементы с положительным счетчиком.
counter = Counter ({'Dog': 2, 'Cat': -1, 'Horse': 0})
# элементы ()
elements = counter.elements () # не возвращает элементы с количеством 0 или меньше
для значения в элементах:
печать (значение)
Приведенный выше код напечатает «Собака» два раза, потому что его счетчик равен 2.Другие элементы будут проигнорированы, потому что у них нет положительного счета. Counter — это неупорядоченная коллекция, поэтому элементы возвращаются в произвольном порядке.
most_common (n)
Этот метод возвращает наиболее общие элементы из счетчика. Если мы не указываем значение «n», то отсортированный словарь возвращается из наиболее распространенных и наименее распространенных элементов. Мы можем использовать нарезку, чтобы получить наименее распространенные элементы в этом отсортированном словаре.
counter = Counter ({'Dog': 2, 'Cat': -1, 'Horse': 0})
# наиболее общий()
most_common_element = счетчик.most_common (1)
print (most_common_element) # [('Собака', 2)]
наименьший_коммон_элемент = counter.most_common () [: - 2: -1]
print (наименее общий_элемент) # [('Кот', -1)]
subtract () и update ()
Счетчик subtract () Метод
используется для вычитания количества элементов из другого счетчика. update () Метод
используется для добавления счетчиков из другого счетчика.
counter = Счетчик ('ababab')
print (counter) # Counter ({'a': 3, 'b': 3})
c = счетчик ('abc')
print (c) # Counter ({'a': 1, 'b': 1, 'c': 1})
# вычесть
счетчик.вычесть (с)
print (counter) # Counter ({'a': 2, 'b': 2, 'c': -1})
# Обновить
counter.update (c)
print (counter) # Counter ({'a': 3, 'b': 3, 'c': 0})
Python Арифметические операции счетчиков
Мы можем выполнять некоторые арифметические операции и со счетчиками, как и числа. Однако с помощью этих операций возвращаются только элементы с положительным счетчиком.
# арифметические операции
c1 = счетчик (a = 2, b = 0, c = -1)
c2 = счетчик (a = 1, b = -1, c = 2)
c = c1 + c2 # возвращать элементы, имеющие только количество + ve
print (c) # Counter ({'a': 3, 'c': 1})
c = c1 - c2 # сохраняет только + ve элементов
print (c) # Counter ({'a': 1, 'b': 1})
c = c1 & c2 # пересечение min (c1 [x], c2 [x])
print (c) # Counter ({'a': 1})
c = c1 | c2 # union max (c1 [x], c2 [x])
print (c) # Counter ({'a': 2, 'c': 2})
Разные операции со счетчиком Python
Давайте посмотрим на некоторые фрагменты кода для разных операций, которые мы можем выполнять с объектами счетчика.
counter = Counter ({'a': 3, 'b': 3, 'c': 0})
# разные примеры
print (сумма (counter.values ())) # 6
print (list (counter)) # ['a', 'b', 'c']
print (set (counter)) # {'a', 'b', 'c'}
print (dict (counter)) # {'a': 3, 'b': 3, 'c': 0}
print (counter.items ()) # dict_items ([('a', 3), ('b', 3), ('c', 0)])
# удалить 0 или отрицательное число элементов
counter = Counter (a = 2, b = 3, c = -1, d = 0)
counter = + counter
print (counter) # Counter ({'b': 3, 'a': 2})
# очистить все элементы
counter.clear ()
print (counter) # Counter ()
Это все для класса Python Counter.
Ссылка: Python Docs
.Счетчик
на Python — AskPython
Счетчик является подклассом dict
и является частью модуля Collections . Он используется для подсчета хешируемых объектов.
Это неупорядоченная коллекция, в которой элементы хранятся как ключи словаря, а их счетчики являются значениями.
Формат объекта счетчика: {element1: count1, element2: count2}
Элементы подсчитываются из итерации или инициализируются из другого сопоставления (или счетчика)
Инициализация объекта Counter
выполняется с помощью вызова Counter ()
.
Мы также можем передать итерацию в вызов и получить соответствующий сопоставленный объект.
>>> из коллекции импорта Counter >>> # Пустой объект счетчика >>> c = Счетчик () >>> c Счетчик () >>> # Кортеж значений >>> d = Счетчик (a = 1, b = 2, c = 1) >>> d Счетчик ({'b': 2, 'a': 1, 'c': 1}) >>> # Передаем список, который может повторяться >>> e = Counter (['a', 'b', 'a', 'c']) >>> e Счетчик ({'a': 2, 'b': 1, 'c': 1}) >>> # Передаем строку, также повторяемую >>> f = Счетчик ('красное блюдо') >>> f Счетчик ({'d': 2, 'r': 1, 'e': 1, '-': 1, 'i': 1, 's': 1, 'h': 1}) >>> # Передать словарь >>> g = Counter ({'a': 10, 'b': 11}) >>> г Счетчик ({'b': 11, 'a': 10})
Обратите внимание, что когда отображается объект Counter, пары ключ-значение отображаются в порядке убывания счетчика.
Объекты
Counter имеют интерфейс словаря, за исключением того, что они возвращают нулевое значение счетчика пропущенных элементов вместо того, чтобы вызывать KeyError
.
Методы счетчика
1. Подсчитайте количество отдельных элементов
Счетчики отдельных элементов доступны так же, как и в Словаре, что означает, что counter_object [key]
дает счет key
.
>>> c = Счетчик (a = 1, b = 2, c = 1) >>> c Счетчик ({'b': 2, 'a': 1, 'c': 1}) >>> c ['b'] 2 >>> c ['d'] # Не выдает KeyError, в отличие от словаря 0
2.Установить количество элементов
Чтобы установить количество элементов, используйте counter_object [key] = value
. Если ключ
не существует, он добавляется в словарь счетчиков вместе с новым счетчиком.
>>> c = Счетчик (a = 1, b = 2, c = 1) >>> c Счетчик ({'b': 2, 'a': 1, 'c': 1}) >>> c ['d'] = 4 >>> c Счетчик ({'d': 4, 'b': 2, 'a': 1, 'c': 1})
3. Снимите элементы со стойки
Чтобы удалить ключ из объекта Counter, используйте del counter_object [key]
.
>>> дель с ['д'] >>> c Счетчик ({'b': 2, 'a': 1, 'c': 1})
4. элементы ()
Этот метод возвращает итератор по элементам, значения которых повторяются столько раз, сколько их количество. Этот метод игнорирует всех элементов, у которых счетчик меньше единицы.
>>> c Счетчик ({'b': 2, 'a': 1, 'c': 1}) >>> c ['d'] = -1 >>> c >>> c.elements () <объект itertools.chain по адресу 0x102e2a208> >>> тип (c.элементы ()) <класс itertools.chain> >>> для i в c.elements (): ... печать (я) ... а б б c >>> список (c.elements ()) ['a', 'b', 'b', 'c'] >>> c ['d'] = -1 >>> c Счетчик ({'b': 2, 'a': 1, 'c': 1, 'd': -1}) >>> # Игнорирует d, поскольку count [d] <1 >>> список (c.elements ()) ['a', 'b', 'b', 'c']
5. most_common (n)
Возвращает список n наиболее распространенных элементов и их количество от наиболее распространенных до наименьших.Если n опущено или Нет
, most_common ()
возвращает всех элементов в счетчике. Элементы с равным количеством упорядочиваются произвольно.
>>> c Счетчик ({'b': 2, 'a': 1, 'c': 1, 'd': -1}) >>> c.most_common () [('b', 2), ('a', 1), ('c', 1), ('d', -1)] >>> c.most_common (2) [('b', 2), ('a', 1)]
6. вычитание (итерация / отображение)
Возвращает отображение / итерацию после вычитания содержимого двух итераций / отображений.Элементы не заменяются, а вычитается только их количество.
>>> a = Счетчик ('красный синий') >>> а Счетчик ({'e': 2, 'r': 1, 'd': 1, 'b': 1, 'l': 1, 'u': 1}) >>> b = Counter ('blueorange') >>> б Счетчик ({'e': 2, 'b': 1, 'l': 1, 'u': 1, 'o': 1, 'r': 1, 'a': 1, 'n': 1 , 'g': 1}) >>> # Вычитает b из a и соответственно обновляет a >>> a.subtract (b) >>> а Counter ({'d': 1, 'r': 0, 'e': 0, 'b': 0, 'l': 0, 'u': 0, 'o': -1, 'a': -1, 'n': -1, 'g': -1})
7.обновление (итерация / отображение)
Это похоже на subtract ()
, но только добавляет счетчики, а не вычитает их.
>>> a = Счетчик ('12321') >>> b = Счетчик ('23432') >>> а Счетчик ({'1': 2, '2': 2, '3': 1}) >>> б Счетчик ({'2': 2, '3': 2, '4': 1}) >>> # Добавить счетчики в >>> a.update (b) >>> а Счетчик ({'2': 4, '3': 3, '1': 2, '4': 1})
Другие методы Counter ()
-
счетчик.clear ()
используется для сброса счетчиков всех элементов в счетчике -
counter.values ()
возвращает объект dict-values , используемый для других методов, таких какsum ()
, чтобы получить общее количество всех элементов. -
список (счетчик)
используется для перечисления всех уникальных элементов -
набор (счетчик)
преобразует счетчик в набор -
счетчик.items ()
возвращает список из(ключ, значение)
пар в счетчике. -
counter + = Counter ()
удаляет все элементы с нулевым или отрицательным счетом
Арифметические операции со счетчиками
Мы можем использовать основные арифметические операции со счетчиками, такие как сложение, вычитание, объединение и пересечение.
>>> c = Счетчик (a = 3, b = 1) >>> d = Счетчик (a = 1, b = 2) >>> c + d Счетчик ({'a': 4, 'b': 3}) >>> # Вычтите c, d, сохраняя только положительные значения >>> c - d Счетчик ({'a': 2}) >>> # Пересечение c, d (Min (c, d)) >>> c & d Счетчик ({'a': 1, 'b': 1}) >>> # Объединение c, d (Макс (c, d)) >>> c | d Счетчик ({'a': 3, 'b': 2})
Заключение
Мы узнали о классе Counter, который дает нам объекты, отображающие каждый элемент на его счетчик.Мы также узнали о некоторых методах, которые предоставляет collection.Counter для управления объектами Counter.
Список литературы
Документация по коллекциям Python
: https://docs.python.org/2/library/collections.html
JournalDev Статья о счетчике Python: https://www.journaldev.com/20806/python-counter-python-collections-counter
.