Бриллиант из коробки: Python-библиотека collections
2026-02-21 11:03 Diff

#статьи

  • 18 авг 2021
  • 0

Не просто библиотека, а та самая библиотека.

Dana Moskvina / Skillbox Media

Кандидат философских наук, специалист по математическому моделированию. Пишет про Data Science, AI и программирование на Python.

Язык программирования Python, по сути, состоит из библиотек. Каждую из них можно установить, а затем импортировать в свой код и использовать как вам нужно. Наиболее полезные включаются в установку по умолчанию — они появляются на вашем компьютере вместе с собственно интерпретатором Python.

Библиотека collections — одна из таких библиотек «из коробки». В ней содержатся мощные, удобные и быстродействующие альтернативы встроенным типам данных: словарям, спискам, кортежам.

Это может пригодиться в задачах подсчёта значений, организации сбора и быстрой конвертации данных из файлов CSV и баз SQL. Говорят, что разработчики и дата-сайентисты, открывшие для себя библиотеку collections, удивляются: «Как это я раньше жил без неё?»

Изображение: Киностудия «Мосфильм»

Обычный словарь dict в Python содержит пары вида «ключ:значение». Значение из словаря можно запросить по ключу. В случае если запрашиваемого ключа в словаре нет, Python выдаст ошибку:

my_dict = {'a':1, 'b':2, 'c':3} my_dict['a'] >>> 1 my_dict['d'] >>> Traceback (most recent call last): >>> File "<pyshell#2>", line 1, in <module> >>> my_dict['d'] >>> KeyError: 'd'

Поведение логичное, но не слишком удобное для работы. Словарь defaultdict из библиотеки collections поступает иначе: если запросить у такого продвинутого словаря ключ, которого в нём нет, он не обидится и не выкинет ошибку, а вместо этого:

  • создаст этот ключ;
  • создаст к нему значение, которое будет иметь тип, оговорённый по умолчанию («по дефолту» — отсюда, кстати, и название), — например, целое число или строку;
  • и — тадамм! — вернёт вам это значение.

Строго говоря, в Python существуют стандартные методы словарей .setdefault() и .get() со сходной функциональностью, но они сложнее в использовании — надо каждый раз указывать значение по умолчанию. А здесь мы сразу задаём тип для всех таких значений и далее просто обращаемся по ключу.

Как это работает:

from collections import defaultdict my_new_dict = defaultdict(int, my_dict) my_new_dict >>> defaultdict(<class 'int'>, {'a': 1, 'b': 2, 'c': 3}) my_new_dict['d'] >>> 0 my_new_dict >>> defaultdict(<class 'int'>, {'a': 1, 'b': 2, 'c': 3, 'd': 0})

В первой строчке импортировали модуль defaultdict из библиотеки collections.

Во второй — превратили наш предыдущий словарь my_dict в словарь нового типа my_new_dict: «int», стоящий первым в скобках, означает, что значениями, создаваемыми по умолчанию, будут целые числа, а конкретно число ноль.

Далее мы выводим наш my_new_dict, чтобы посмотреть, что в нём. Интерпретатор Python показывает нам:

  • тип словаря: defaultdict;
  • тип значений по умолчанию: int;
  • а также текущее содержимое нашего словаря. Ключа «d» в нём нет, как и в оригинальном словаре my_dict.

В следующей строке мы как раз и запрашиваем элемент с этим ключом. И, о чудо, my_new_dict выдаёт нам значение — оно равно 0.

Смотрим снова на содержимое нашего словаря и видим, что там появилась новая пара 'd': 0.

Вы наверняка догадались, что вместо int при создании словаря типа defaultdict можно писать любые стандартные типы данных: float, list, str — и даже другие словари dict. И новые элементы, создаваемые при первом обращении к ключу, будут именно этого типа: нули, пустые списки, строки и словари соответственно.

my_new_dict_2 = defaultdict(dict, my_dict) my_new_dict_2 >>> defaultdict(<class 'dict'>, {'a': 1, 'b': 2, 'c': 3}) my_new_dict_2['e'] >>> {} my_new_dict_2 >>> defaultdict(<class 'dict'>, {'a': 1, 'b': 2, 'c': 3, 'e': {}})

И, конечно, словарь defaultdict поддерживает все методы обычных питоновских словарей: .items(), .values(), .keys() и другие.

Кортеж (tuple, его часто называют «неизменяемым списком») в Python содержит некоторое количество элементов, к каждому из которых можно обратиться только по его индексу.

simple_tuple = (1, 'a', 123.4) simple_tuple[1] >>> 'a'

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

Здесь снова приходит на помощь библиотека collections, а конкретно её функция namedtuple. Это расширение над встроенными кортежами, которое даёт имя каждому элементу кортежа, а точнее — создаёт именованные поля, в которые мы, как в строку в таблице, складываем значения.

В итоге получаем что-то вроде неизменяемого (immutable) словаря, только гораздо легче читаемого.

from collections import namedtuple fruit = namedtuple('fruit','number sort color') apple = fruit(number=5, sort='Antonovka', color='red') orange = fruit(number=7, sort='Navel Late', color='yellow')

Мы импортировали функцию namedtuple из collections. Затем создали конструктор именованных кортежей fruit, указав:

  • общее название тех кортежей, которые мы будем создавать ('fruit');
  • строку, содержащую имена полей именованного кортежа. Имена разделены в строке пробелом.

А после этого создали два именованных кортежа: apple и orange.

Теперь можно обращаться к элементам этих кортежей не по индексу, а по именам полей number, sort и color. Они являются атрибутами именованных кортежей, то есть используются через точку и без скобок.

apple.sort >>> 'Antonovka' orange.color >>> 'yellow' # обращение по индексам работает по-прежнему apple[2] >>> 'red'

Именованные кортежи обладают всеми свойствами простых кортежей, в том числе быстродействием и неизменяемостью, а также поддерживают их методы. В документации есть хорошие примеры использования.

Counter — это разновидность словаря Python, созданная для подсчёта, что понятно из названия. Ключами в ней выступают подсчитываемые элементы, а значениями — их количества. Посмотрим на примерах, как она работает.

from collections import Counter # строки c = Counter('абвабббаввабббвавабг') print(c) >>> Counter({'б': 8, 'а': 6, 'в': 5, 'г': 1}) # списки lst = [5,6,7,1,3,9,9,1,2,5,5,7,7] c = Counter(lst) print(c) >>> Counter({5: 3, 7: 3, 1: 2, 9: 2, 6: 1, 3: 1, 2: 1})

Чаще всего в строке встречается буква «б» — 8 раз, а в списке — числа 5 и 7, по 3 раза. Подсчёт слов в предложении сводится к подсчёту элементов списка:

s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() # вернёт список слов Counter(words) >>> Counter({'зима': 3, 'ни': 2, 'по': 1, 'полгода': 1, 'звоночка': 1, 'письма': 1})

Counter поддерживает все методы словарей плюс дополнительные методы elements() и most_common(n). Первый выдаёт список из элементов, количество которых больше нуля, а второй выводит список из n пар самых частых элементов в виде кортежей (элемент, количество).

c = Counter(a=3, b=2, c=1, d=-2) # указали количества элементов sorted(c.elements()) >>> ['a', 'a', 'a', 'b', 'b', 'c'] s = 'зима зима зима по полгода ни звоночка ни письма' words = s.split() Counter(words).most_common(2) # 2 самых частых элемента и их количество >>> [('зима', 3), ('ни', 2)]

Типовые примеры использования Counter():

sum(c.values()) # сумма всех количеств c.clear() # сброс всех количеств list(c) # список элементов set(c) # преобразование во множество dict(c) # преобразование в обычный словарь c.items() # преобразование в список кортежей (элемент, количество) Counter(dict(list_of_pairs)) # обратное преобразование из списка кортежей вида (элемент, количество) c.most_common()[:-n-1:-1] # n самых редких элементов c += Counter() # удаление элементов с отрицательными и нулевыми количествами

Удобные инструменты из библиотеки collections помогут быстро разобраться с большим количеством однотипных данных: обработать их, преобразовать и передать дальше. Используйте collections везде, где требуется скорость работы, надёжный учёт данных и хорошая читаемость кода.

На курсе «Профессия Python-разработчик» вы изучите и другие бриллианты из многочисленного семейства библиотек Python. Все они помогут вам в учёбе и дальнейшем трудоустройстве. Приходите!

Бесплатный курс по Python ➞
Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу