collections
В стандартную библиотеку Python входит модуль collections содержащий дополнительные структуры данных. Мы поговорим о некоторых и обсудим их пользу.
А конкретно:
defaultdictOrderedDictcounterdequenamedtupleenum.Enum(вне модуля; Python 3.4+)
defaultdict
defaultdictЯ использую defaultdict время от времени. В отличие от dict нам не нужно проверять существует ли ключ в словаре или нет. В результате мы можем писать следующий код:
from collections import defaultdict
colours = (
('Yasoob', 'Yellow'),
('Ali', 'Blue'),
('Arham', 'Green'),
('Ali', 'Black'),
('Yasoob', 'Red'),
('Ahmed', 'Silver'),
)
favourite_colours = defaultdict(list)
for name, colour in colours:
favourite_colours[name].append(colour)
print(favourite_colours)
# Вывод:
# defaultdict(<type 'list'>,
# {'Arham': ['Green'],
# 'Yasoob': ['Yellow', 'Red'],
# 'Ahmed': ['Silver'],
# 'Ali': ['Blue', 'Black']
# })Другим популярным случаем использования defaultdict является добавление элементов в список внутри словаря. Если ключ не существует в словаре, то вы упрётесь в KeyError. defaultdict позволяет обойти эту проблему аккуратным образом. Для начала, позвольте привести пример использования dict с исключением KeyError, а затем мы посмотрим на пример с defaultdict.
Проблема:
Решение:
Вы можете вывести в консоль some_dict используя json.dumps. Вот пример:
OrderedDict
OrderedDictOrderedDict сохраняет элементы в порядке добавление в словарь. Изменение значения ключа не изменяет его позиции. При этом удаление и повторное добавление перенесет ключ в конец словаря.
Проблема:
Решение:
counter
counterCounter позволяет подсчитывать частоту определенных элементов. К примеру, мы можем использовать его, чтобы посчитать сколько любимых цветов у каждого человека:
Мы также можем посчитать частоту строк в файле. Пример:
deque
dequedeque предлагает нам двустороннюю очередь, которая позволяет добавлять и удалять элементы с обеих сторон. Для начала, вам нужно импортировать модуль deque из библиотеки collections:
Теперь мы можем создать экземпляр двусторонней очереди:
Очередь работает подобно списку в Python и имеет схожие методы. Например, вы можете:
Мы можем отрезать элементы с обеих сторон очереди:
Мы также можем ограничить число элементов, которые может хранить очередь. Таким образом при достижении максимального числа элементов очередь начнет отрезать элементы с другого конца. Это проще объяснить на примере:
Теперь, когда мы попытаемся добавить 31-й элемент - очередь отрежет первый элемент с другого конца. Вы также можете добавлять элементы к очереди с обоих концов:
namedtuple
namedtupleВы уже должны быть знакомы с кортежами. Кортеж в Python это неизменяемый список, который позволяет хранить объекты, разделенные запятой. Они практически идентичны спискам, за исключением нескольких важных особенностей. В отличие от списков, вы не можете изменить элемент кортежа. В то же время вы можете обращаться к элементам кортежа по индексам:
Отлично, так что же тогда namedtuples? Этот модуль открывает доступ к удобной структуре данных для простых задач. С помощью именованных кортежей вам не обязательно использовать индексы для обращения к элементам кортежа. Вы можете думать об именованных кортежах как о словарях, но в отличие от словарей они неизменяемы.
Теперь вы можете видеть, что мы можем обращаться к элементам именованного кортежа при помощи их имени и . (точки). Давайте чуть подробнее на этом остановимся. Именованный кортеж имеет два обязательных аргумента. Это имя самого кортежа и имена полей кортежа. В примере выше имя нашего кортежа Animal, имена полей соответственно: name, age и type. Именованный кортеж позволяет создавать само-документированные кортежи. Вы сможете легко понять код при первом же взгляде на него. И, поскольку вы не привязаны к индексам, у вас открывается больше возможностей по поддержке своего кода. Помимо этого, именованные кортежи не создают словари для каждого экземпляра, они легковесны и не требуют больше памяти чем обычные кортежи. Это делает их быстрее словарей. Тем не менее, помните, что как и в случае с обычными кортежами, именованный кортеж неизменяем. Это означает, что такой код работать не будет:
Вы должны использовать именованные кортежи для улучшения читаемости кода. Они обратносовместимы с обычными кортежами. Это значит, что вы можете использовать численные индексы с именованными кортежами:
И последнее, вы можете сконвертировать именованный кортеж в словарь. Вот так:
enum.Enum (Python 3.4+)
enum.Enum (Python 3.4+)Другой полезной структурой данных является enum. Он доступен в модуле enum, начиная с Python 3.4 (также в PyPI как бекпорт под именем enum34). Enums (перечисляемый тип) это простой способ организации разных вещей.
Давайте рассмотрим именованный кортеж Animal из прошлого примера. У него есть поле type. Проблема в том, что его тип - строка. Это создаёт нам несколько проблем. Что если пользователь ввёл Cat, поскольку нажал Shift? Или CAT? Или kitten?
Перечисление может помочь обойти эту проблему, позволив не использовать строки. Рассмотрим пример:
Так у нас куда меньше шансов допустить ошибку. При этом мы должны быть конкретны и использовать только перечисление для определения полей.
Существует три способа получения доступа к перечисляемым элементам. Например, все три метода, представленные ниже, дадут вам значения поля cat:
Это было короткое погружение в библиотеку collections. Обязательно ознакомьтесь с официальной документацией после чтения этой главы.
Last updated