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

Счетчик – подсчет хэшируемых объектов

Автор оригинала: Doug Hellmann.

Counter – это контейнер, который отслеживает, сколько раз добавляются эквивалентные значения. Его можно использовать для реализации тех же алгоритмов, для которых другие языки обычно используют пакетные или мультимножественные структуры данных.

Инициализация

Counter поддерживает три формы инициализации. Его конструктор может быть вызван с последовательностью элементов, словарем, содержащим ключи и счетчики, или с использованием аргументов ключевого слова, которые отображают имена строк в счетчики.

collections_counter_init.py

import collections

print(collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print(collections.Counter({'a': 2, 'b': 3, 'c': 1}))
print(collections.Counter(a2, b3, c1))

Результаты всех трех форм инициализации одинаковы.

$ python3 collections_counter_init.py

Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

Пустой Counter может быть создан без аргументов и заполнен с помощью метода update () .

collections_counter_update.py

import collections

c  collections.Counter()
print('Initial :', c)

c.update('abcdaab')
print('Sequence:', c)

c.update({'a': 1, 'd': 5})
print('Dict    :', c)

Значения счетчика увеличиваются на основе новых данных, а не заменяются. В предыдущем примере счетчик для a изменяется от 3 до 4 .

$ python3 collections_counter_update.py

Initial : Counter()
Sequence: Counter({'a': 3, 'b': 2, 'c': 1, 'd': 1})
Dict    : Counter({'d': 6, 'a': 4, 'b': 2, 'c': 1})

Доступ к счетчикам

После заполнения Counter его значения можно получить с помощью API словаря.

collections_counter_get_values.py

import collections

c  collections.Counter('abcdaab')

for letter in 'abcde':
    print('{} : {}'.format(letter, c[letter]))

Counter не вызывает KeyError для неизвестных элементов. Если значение не было обнаружено во вводе (как в случае с e в этом примере), его счетчик равен 0 .

$ python3 collections_counter_get_values.py

a : 3
b : 2
c : 1
d : 1
e : 0

Метод elements () возвращает итератор, который производит все элементы, известные Counter .

collections_counter_elements.py

import collections

c  collections.Counter('extremely')
c['z']  0
print(c)
print(list(c.elements()))

Порядок элементов не гарантируется, и элементы с количеством меньше или равным нулю не включаются.

$ python3 collections_counter_elements.py

Counter({'e': 3, 'x': 1, 't': 1, 'r': 1, 'm': 1, 'l': 1, 'y': 1,
'z': 0})
['e', 'e', 'e', 'x', 't', 'r', 'm', 'l', 'y']

Используйте most_common () , чтобы создать последовательность из n наиболее часто встречающихся входных значений и их соответствующих счетчиков.

collections_counter_most_common.py

import collections

c  collections.Counter()
with open('/usr/share/dict/words', 'rt') as f:
    for line in f:
        c.update(line.rstrip().lower())

print('Most common:')
for letter, count in c.most_common(3):
    print('{}: {:>7}'.format(letter, count))

В этом примере подсчитывается количество букв, встречающихся во всех словах системного словаря, для получения частотного распределения, а затем печатаются три наиболее распространенные буквы. Если оставить аргумент для most_common () , вы получите список всех элементов в порядке частоты.

$ python3 collections_counter_most_common.py

Most common:
e:  235331
i:  201032
a:  199554

Арифметика

Экземпляры Counter поддерживают арифметические операции и операции с наборами для агрегирования результатов. В этом примере показаны стандартные операторы для создания новых экземпляров Counter , но операторы на месте , , и также поддерживаются.

collections_counter_arithmetic.py

import collections

c1  collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2  collections.Counter('alphabet')

print('C1:', c1)
print('C2:', c2)

print('\nCombined counts:')
print(c1 + c2)

print('\nSubtraction:')
print(c1 - c2)

print('\nIntersection (taking positive minimums):')
print(c1 & c2)

print('\nUnion (taking maximums):')
print(c1 | c2)

Каждый раз, когда в результате операции создается новый Counter , любые элементы с нулевым или отрицательным счетчиком отбрасываются. Счетчик для a одинаков для c1 и c2 , поэтому при вычитании его значение равно нулю.

$ python3 collections_counter_arithmetic.py

C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'l': 1, 'p': 1, 'h': 1, 'b': 1, 'e': 1, 't': 1})

Combined counts:
Counter({'a': 4, 'b': 4, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

Subtraction:
Counter({'b': 2, 'c': 1})

Intersection (taking positive minimums):
Counter({'a': 2, 'b': 1})

Union (taking maximums):
Counter({'b': 3, 'a': 2, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})