Модуль collections
Специализированные контейнеры, делающие повседневный подсчёт, группировку и работу с очередями тривиальными
dict и list справляются почти со всем, но три специализированных контейнера из стандартного модуля collections убирают шаблонный код, который иначе пришлось бы писать вручную каждый день. Counter подсчитывает элементы, defaultdict автоматически подставляет значение для отсутствующих ключей, а deque добавляет и удаляет с обоих концов за постоянное время. Ни один из них не является чем-то экзотическим; каждый — это привычная вам структура данных, где утомительные части уже сделаны за вас.
- подсчитывать элементы с помощью
Counterи находить самые частые, - группировать и накапливать значения с
defaultdictбезKeyError, - строить быстрые очереди и стеки с
deque, - объяснить, почему
deque.popleft()лучшеlist.pop(0), - выбирать правильный контейнер под задачу.
1. Зачем выходить за пределы обычных dict и list?
Вы уже уверенно создаёте словари и списки. Но некоторые шаблоны повторяются снова и снова: подсчёт того, сколько раз встречается каждое значение, сбор элементов в группы по некоторому свойству или использование списка как очереди, из которой удаляют элементы с начала. У каждого есть чистое решение на чистом Python, и у каждого есть раздражающая мелочь.
Подсчёт вручную означает проверку существования ключа перед его увеличением:
counts = {}
for word in words:
if word not in counts:
counts[word] = 0
counts[word] += 1
Группировка вручную имеет ту же форму — вам нужно создать пустой список при первом появлении ключа. А использование обычного списка как очереди незаметно медленно: list.pop(0) сдвигает каждый оставшийся элемент на одну позицию влево, поэтому удаление с начала списка из n элементов стоит O(n) каждый раз.
Модуль collections поставляет три контейнера, которые стирают именно эти мелочи. Вы импортируете их один раз, и шаблонный код исчезает:
from collections import Counter, defaultdict, deque