Это продолжение вступительного поста о инструменте python Counter . Если вы хотите прочитать это, прежде чем вернуться к этому, вы можете найти его здесь .
Можем ли мы применить счетчик к любой форме данных?
Счетчик – это удивительный инструмент, который упрощает задачу подсчета предметов, но, нет! он работает только на итераблях – это еще не все, так что продолжайте читать. В то же время, что такое итерабельность? В основных терминах итеративная функция хранит последовательность значений или символов, которые можно пересечь.
Давайте рассмотрим примеры:
>>> a = [1, 2, 3, 4, 5, 6, 7, 3, 3] >>> b = (1, 2, 3, 4, 5, 6, 7, 2, 2) >>> c = "This is a string." >>> m = 123456
a является итеративным. Это список целых чисел. Вы можете пересечь эти числа, одно за другим. b также является итеративным. Это кортеж, содержащий значения также одно за другим. c
также является итеративным. Это последовательность символов. m
не является итеративным. Это целое число, а не последовательность.
Что происходит, когда мы применяем a Counter к a, b, c и m? Во-первых, мы импортируем Counter из коллекций
>>> from collections import Counter
Далее мы применим Счетчик к a , b и c .
>>> Counter(a) Counter({3: 3, 1: 1, 2: 1, 4: 1, 5: 1, 6: 1, 7: 1})
>>> Counter(b) Counter({2: 3, 1: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1})
>>> Counter(c) Counter({'i': 3, 's': 3, ' ': 3, 'T': 1, 'h': 1, 'a': 1, 't': 1, 'r': 1, 'n': 1, 'g': 1, '.': 1})
Как и всегда, Counter дал нам количество раз, когда каждый элемент встречается в данных итерациях.
Для a целое число 3 происходит три раза, и каждое из других чисел происходит только один раз. Для b , целое число 2 происходит три раза, и каждое из других чисел происходит только один раз. Поведение с c интересно. Счетчик давал нам количество раз, когда каждая буква или символ встречались в тексте. i , s и символ пробела встречался три раза каждый , а каждый из других символов встречался только один раз.
Что происходит с m ?
>>> Counter(m) Traceback (most recent call last): File "", line 1, in File "C:\Users\DELL\AppData\Local\Programs\Python\Python37-32\lib\collections\__init__.py", line 566, in __init__ self.update(*args, **kwds) File "C:\Users\DELL\AppData\Local\Programs\Python\Python37-32\lib\collections\__init__.py", line 653, in update _count_elements(self, iterable) TypeError: 'int' object is not iterable
Мы получаем TypeError , кричащий, что m не является итеративным . Мы можем спокойно согласиться с этим: счетчики работают только с итерациями.
Можем ли мы использовать счетчик осмысленно с каждой итерацией?
Давайте посмотрим…
>>> d = {1, 2, 3, 4, 5, 6, 7, 3, 3} >>> Counter(d) Counter({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1})
Это не то, чего мы ожидали. Счетчик говорит, что каждое число произошло только один раз, но мы знаем 3 произошло это трижды.
Причина проста. d является набором и не может содержать дубликатов. Даже несмотря на то, что мы присвоили несколько номеров с 3 повторяясь несколько раз, дубликаты были удалены до того, как они были сохранены в переменной d . Давайте разберем это в коде.
>>> d = {1, 2, 3, 4, 5, 6, 7, 3, 3} >>> >>> # what does d contain? >>> d {1, 2, 3, 4, 5, 6, 7} >>> >>> Counter(d) Counter({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1})
Теперь мы можем понять, почему мы получили такой результат. Проблема заключалась в том, что у d не было дубликатов, и Счетчик по праву считал только один из каждого числа. Таким образом, мы не можем использовать Счетчик осмысленно на множестве, даже если множество является итеративным.
Давайте посмотрим, что происходит со словарем.
>>> e = {'num1': 1, 'num2':2, 'num3':3, 'num4':3, 'num5':3} >>> >>> # What does e contain? >>> e {'num1': 1, 'num2': 2, 'num3': 3, 'num4': 3, 'num5': 3} >>> Counter(e) Counter({'num3': 3, 'num4': 3, 'num5': 3, 'num2': 2, 'num1': 1}) >>> >>> >>> >>> f = {'str1':'this', 'str2':'that', 'str3':'then', 'str4':'then', 'str5':'that'} >>> >>> # What does f contain? >>> f {'str1': 'this', 'str2': 'that', 'str3': 'then', 'str4': 'then', 'str5': 'that'} >>> Counter(f) Counter({'str1': 'this', 'str3': 'then', 'str4': 'then', 'str2': 'that', 'str5': 'that'}) >>> >>>
Выше мы имеем два словаря, содержащих различные типы значений. Первый, e , содержит числа, а второй, f , содержит строки. Они ведут себя аналогично с Counter; Counter, похоже, не делал никакого подсчета и возвращал пары ключ-значение в словарях как есть. За исключением изменения порядка – значения сортируются в порядке убывания. Давайте оставим причину для другого поста .
По-видимому, использование Counter в словаре также не очень значимо, если только значения словаря не являются числами. В этом случае значения обрабатываются как подсчеты ключей , как показано в примере e .
Таким образом, даже если мы можем пройти через словарь – я частично считаю его итеративным – это не очень значимо, используя Счетчик на нем. Я уже упоминал, что словарь частично итеративен, потому что вы можете итерировать по его ключам, а не по его значениям. Давайте продемонстрируем это:
>>> # mydict is a sample dictionary containing >>> # information about John Doe >>> mydict = {'name':'John Doe', 'id':'DST024315', 'age':40, 'country':'Germany'} >>> >>> # let's iterate over it >>> for item in mydict: ... print(item) ... name id age country >>> >>> # the keys of the dictionary were printed >>> # instead of the key-value pairs or values
Как мы уже видели, a. Счетчики работают только на итерациях b. Использование Counter может быть заметно не на всех итерациях.
Мы заметили, что полезно применять Счетчики к спискам, кортежам и строкам, но не к наборам и словарям, когда мы хотим подсчитать отдельные значения. Кроме того, он хорошо работает и на deque , еще одном инструменте, похожем на list , но с дополнительными функциями. Вы можете узнать больше об использовании a deque .
Наконец, когда мы применили Счетчик к тексту, он дал нам количество символов. Что, если бы мы хотели считать слова, а не символы? Следите за следующим постом на Counter .