Питоновский модуль collections - предоставляет специализированные типы данных, на основе словарей, кортежей, множеств, списков. Модуль collections позволяет подсчитать все элементы коллекций. Если бы вы работали c PHP, то вам пришлось использовать array_count_values. Если выполнять подсчёт циклом for, то пришлось бы совершать массу лишних манипуляций. В этом случае вам пришлось бы создавать дополнительные итераторы счётчики.
В этой статье мы рассмотрим тип данных Counter. Обращаться к типу придётся через точку (точечная нотация) collections.Counter. Counter - вид словаря, который позволяет нам считать количество неизменяемых объектов. На на выводе у вас будут ключи и значения.
#!/usr/bin/python3
import collections
c = collections.Counter()
for word in ['Python', 'Python', 'Ruby', 'HTML', 'Javascript', 'CSS', 'CSS']:
c[word] += 1
# выводим результат
print(c)
'''
вывод:
Counter({'CSS': 2, 'Python': 2, 'HTML': 1, 'Ruby': 1, 'Javascript': 1})
'''
#определяем тип переменной с
print(type(c))
'''
вывод:
<class 'collections.Counter'>
'''
# так нельзя обращаться
print(c.CSS)
'''
вывод:
Traceback (most recent call last):
File "./base.py", line 17, in
print(c.CSS)
AttributeError: 'Counter' object has no attribute 'CSS'
'''
# вывод в виде словаря
print(dict(c))
'''
вывод:
{'Ruby': 1, 'Python': 2, 'CSS': 2, 'Javascript': 1, 'HTML': 1}
'''
c_dict = dict(c)
print(c_dict['Python'])
'''
вывод:
2
'''
В предыдущем примере я показал вам как подсчитывать количество элементов. В этом блоке примеров происходит размножение элементов согласно условию. Ваши строки размножаются заданное количество раз. Данный метод elements возвращает элементы в алфавитном порядке. Это очень удобно! Вам не нужно делать сортировку.
#!/usr/bin/python3
import collections
c = collections.Counter(Python=4, BASH=2, RUBY=0, HTML=-2)
print(list(c.elements()))
'''
вывод:
['BASH', 'BASH', 'Python', 'Python', 'Python', 'Python']
'''
c = collections.Counter({'Python':4, 'BASH':2, 'RUBY':0, 'HTML':2})
print(list(c.elements()))
'''
вывод:
['BASH', 'BASH', 'HTML', 'HTML', 'Python', 'Python', 'Python', 'Python']
'''
Данный метод most_common возвращает элементы в порядке убывания повторяемости. На выходе вы получаете список кортежей. Вам не нужно дополнительно переводить ключи и значения в кортежи. Помните, что кортежи нельзя изменять на протяжении работы скрипта!
#!/usr/bin/python3
import collections
#Если n не указано, возвращаются все элементы.
c = collections.Counter('Python').most_common()
print(c)
'''
вывод:
[('y', 1), ('o', 1), ('P', 1), ('n', 1), ('t', 1), ('h', 1)]
'''
#возвращаются 3 элемента.
c = collections.Counter('Python').most_common(3)
print(c)
'''
вывод:
[('y', 1), ('o', 1), ('P', 1)]
'''
c = collections.Counter(Python=4, BASH=2, RUBY=0, HTML=-2)
print(c.most_common())
'''
вывод:
[('Python', 4), ('BASH', 2), ('RUBY', 0), ('HTML', -2)]
'''
# передаём словарь
c = collections.Counter({'Python':4, 'BASH':2, 'RUBY':0, 'HTML':2})
print(c.most_common())
'''
вывод:
[('Python', 4), ('HTML', 2), ('BASH', 2), ('RUBY', 0)]
'''
# передаём список
c = collections.Counter(['Python','Python','Python','BASH','RUBY','HTML','HTML'])
print(c.most_common())
'''
вывод:
[('Python', 3), ('HTML', 2), ('RUBY', 1), ('BASH', 1)]
'''
'''
c.most_common()[:-n:-1] - n наименее часто встречающихся элементов.
обратите внимание на то что можно использовать подобный фильтр.
Если делать на PHP подобную задачу, то количество кода возрастает в разы.
'''
d = collections.Counter({'Python':4, 'BASH':2, 'RUBY':1, 'HTML':2})
# преобразование в множество.
c_m = d.most_common()[:-4:-1]
print(c_m)
'''
здесь нет ('Python', 4)
вывод:
[('RUBY', 1), ('HTML', 2), ('BASH', 2)]
'''
Метод subtract позволяет массово выполнять вычитание одного значения из другого. Если ключи совпадают, то происходит вычитание значений. Из значений первого массива вычитаются значения второго массива.
#!/usr/bin/python3
import collections
c = collections.Counter(Toyota=4, Mazda=2, Honda=0)
c.subtract(Toyota=2, Mazda=1, Honda=1)
print(dict(c))
'''
вывод:
{'Toyota': 2, 'Mazda': 1, 'Honda': -1}
'''
e = collections.Counter(Toyota=5, Mazda=6, Honda=7)
e.subtract({'Toyota':1, 'Mazda':1, 'Honda':1})
print(dict(e))
'''
вывод:
{'Honda': 6, 'Mazda': 5, 'Toyota': 4}
'''
Покажу вам употребляемые шаблоны для работы с Counter.
#!/usr/bin/python3
import collections
# переводим в словарь.
c = collections.Counter(lang=4, user=2, aplication=1)
print(dict(c))
'''
вывод:
{'user': 2, 'aplication': 1, 'lang': 4}
'''
#сложение значений. в итоге получается общее количество
c_sum = sum(c.values())
print(c_sum)
'''
вывод:
7
'''
# очистить счётчик. В итоге получается None - пустота.
#c_clear = c.clear()
#print(c_clear)
'''
вывод:
None
'''
# список уникальных элементов. На выводе вы не увидите два одинаковых ключа.
c_list = list(c)
print(c_list)
'''
вывод:
['lang', 'aplication', 'user']
'''
# преобразовать в множество.
c_set = set(c)
print(c_set)
'''
вывод:
{'lang', 'user', 'aplication'}
'''
'''
c += Counter() - удаляет элементы, встречающиеся менее одного раза.
после применения collections.Counter() у вас исчезнут ключи с
отрицательными значениями
'''
c = collections.Counter({'Python':4, 'BASH':2, 'RUBY':1, 'HTML':-2})
c += collections.Counter()
print(dict(c))
'''
вывод:
{'Python': 4, 'BASH': 2, 'RUBY': 1}
'''
Благодаря этому типу данных Counter модуля collections вы сможете написать скрипты для подсчёта повторяющихся строк. Допустим, у вас есть текст в котором много ключевых слов. Вы можете сделать вывод в процентном соотношении. Без Counter вам пришлось бы крутить массу циклов. Для генерации списков и множеств применяют различные способы. Используя Counter вы можете легко сгенерировать списки с повторяющимися значениями. Вам могут помочь генераторы списков. Читайте статью как сгенерировать список Python.