Рубрики
Без рубрики

Счетчик Python – Часть 2

Это вторая часть продолжения Counter tutorial. Он исследует определенное неожиданное поведение.

Автор оригинала: Victor Ayi.

Это продолжение вступительного поста о инструменте 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
Что происходит с || m || ?

Мы получаем 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 .