Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs
Рассмотрим еще
один класс Counter модуля connections, входящий в
состав стандартной библиотеки Python. С помощью этого класса удобно
производить подсчет повторяющихся элементов различных последовательностей.
Пользоваться им очень
просто. Пусть у нас имеется строка 'abrakadabra', в которой
необходимо определить число повторений ее символов. Для этого достаточно
создать объект класса Counter с передачей этой строки:
from collections import Counter
s = 'abrakadabra'
syms = Counter(s)
В итоге syms будет словарем с
ключами в виде символов и значениями – числом их повторения в строке s:
print(syms) # Counter({'a': 5, 'b': 2, 'r': 2, 'k': 1, 'd': 1})
Помимо строки в Counter можно
передавать любую итерируемую последовательность, например:
c1 = Counter(['abc', 'cba', 'abc', 'ABC', 'ABC']) # Counter({'abc': 2, 'ABC': 2, 'cba': 1})
c2 = Counter((1, 2, 0, 4, 3, 2, 1, 1)) # Counter({1: 3, 2: 2, 0: 1, 4: 1, 3: 1})
И даже вложенные
последовательности:
c3 = Counter([(1, 2, 3), ('a', 'b'), (1, 2), (1, 2, 3)]) # Counter({(1, 2, 3): 2, ('a', 'b'): 1, (1, 2): 1})
Единственное
ограничение, чтобы подсчитываемые элементы были хэшируемыми, т.к. они являются
ключами словаря. Например, определять вложенные списки вместо кортежей
недопустимо.
Конечно, в самом
простом случае, объект класса Counter можно создать без каких-либо
данных:
c = Counter() # пустой словарь
Или же с набором
любых желаемых пар ключ-значение:
c = Counter({'Alex': 2, 'Mike': 1}) # Counter({'Alex': 2, 'Mike': 1})
w = Counter(car=1, house=2, dog=5) # Counter({'dog': 5, 'house': 2, 'car': 1})
Так как класс Counter унаследован от
встроенного класса словаря dict, то объекты счетчика Counter поддерживают
все стандартные словарные операции и методы. Например:
c['Alex'] # 2
c['Mike'] = 7 # изменение счетчика
c['Serg'] # 0
Обратите
внимание, что для несуществующих ключей класс Counter возвращает
значение 0, в отличие от словаря dict, который в этом случае генерирует
исключение KeyError:
Методы класса Counter
Также несколько
иначе работает метод update() класса Counter. С его помощью
можно к существующим ключам прибавлять новые значения. Например:
c = Counter({'Alex': 2, 'Mike': 1})
c.update({'Alex': 1, 'Serg': 5}) # Counter({'Serg': 5, 'Alex': 3, 'Mike': 1})
Видим, что к
существующим ключам добавляются значения, а изначально несуществующие ключи,
просто создаются.
Следующий метод
most_common(), который присущ именно классу Counter, позволяет
отобрать наиболее встречаемые элементы, то есть, ключи с наибольшими
значениями:
c.most_common(2) # [('Serg', 5), ('Alex', 3)]
c.most_common() # [('Serg', 5), ('Alex', 3), ('Mike', 1)]
Возвращается
список с кортежами в формате ключ-значение. Причем, когда не указывается
количество возвращаемых элементов, то возвращаются все в порядке убывания
частоты.
Следующий метод elements() класса Counter возвращает
итератор для получения всех элементов (ключей):
c.elements() # <itertools.chain object at 0x000002082A4DE1A0>
lst = list(c.elements())
При отображении
списка lst увидим
последовательность:
['Alex', 'Alex',
'Alex', 'Mike', 'Serg', 'Serg', 'Serg', 'Serg', 'Serg']
По сути, здесь
ключи, которые повторяются указанное число раз.
Еще один метод total(), который
появился в версии Python 3.10, возвращает сумму значений всех
счетчиков:
Операции с классом Counter
С объектами
класса Counter можно выполнять
ряд полезных операций. Пусть имеются два следующих объекта:
c1 = Counter(a=1, b=3, c=2)
c2 = Counter(b=2, d=3, f=1)
При сложении
этих объектов будут складываться соответствующие значения ключей словарей и
формироваться новый объект Counter:
c1 + c2 # Counter({'b': 5, 'd': 3, 'c': 2, 'a': 1, 'f': 1})
При вычитании
соответствующие значения вычитаются:
c1 - c2 # Counter({'c': 2, 'a': 1, 'b': 1})
c2 - c1 # Counter({'d': 3, 'f': 1})
Обратите
внимание, что если в процессе вычитания значение ключа становится меньше или
равно нулю, то этот ключ исключается (удаляется).
Кроме того с
объектами c1, c2 можно
выполнять операции объединения и пересечения подобно множествам:
c1 | c2 # объединение: Counter({'b': 3, 'd': 3, 'c': 2, 'a': 1, 'f': 1})
c1 & c2 # пересечение: Counter({'b': 2})
При объединении
одинаковые ключи оставляются с наибольшим значением, а при пересечении – с
наименьшим значением.
Все эти же самые
операции можно записывать и в таком виде:
c1 -= c2
c2 += c1
c1 |= c2
c1 &= c2
Кроме того,
дополнительно существует метод subtract(), который позволяет вычислять
отрицательные значения при вычитании объектов. Например:
c1 = Counter(a=1, b=3, c=2)
c2 = Counter(b=2, d=3, f=1)
c1.subtract(c2) # Counter({'c': 2, 'a': 1, 'b': 1, 'f': -1, 'd': -3})
Изменения
сохраняются в объекте c1.
Вот общие
возможности класса Counter. Использовать его полезно, когда в
программе нужно выполнять подсчет повторяющихся элементов. Довольно часто это
требуется в таких задачах, как:
- анализ текста:
подсчет символов, слов, предложений;
- работа с базами
данных: агрегирование результатов запросов;
- аналитика
больших наборов данных: быстрое получение статистических данных.
Курс по стандартной библиотеке: https://stepik.org/a/259466?utm_source=proproprogs