Краткий обзор модуля Collections в Python
Если реализацию сложно объяснить — идея плоха: The Zen of Python
Python — достаточно мощный ЯП с поддержкой модульного программирования. Модульное программирование представляет собой процесс разделения одной комплексной задачи программирования на несколько маленьких и более управляемых подзадач/модулей. Модули напоминают кирпичики Лего, которые образуют большую задачу, если собрать их вместе.
Модульность обладает множеством преимуществ при написании кода:
- Возможность повторного использования
- Поддерживаемость
- Простота
Функции, модули и пакеты обеспечивают модуляризацию кода в Python.
Введение
Начнем с небольшого обзора модулей и пакетов.
Module
Модуль — это сценарий .py, который можно вызвать в другом сценарии .py. Модуль — это файл, содержащий определения и операторы Python, который участвует в реализации набора функций. Название модуля эквивалентно названию файла с расширением .py
. Для импорта одних модулей из других используется команда import
. Импортируем модуль math.
# import the library
import math
#Using it for taking the log
math.log(10)
2.302585092994046
Встроенные модули в Python
В Python имеется бесчисленное количество встроенных модулей и пакетов практически на любой случай. Полный список можно посмотреть здесь.
При изучении модулей в Python пригодятся две функции — dir
и help
.
- Встроенная функция
dir()
используется для обнаружения функций, реализованных в каждом модуле. Она возвращает отсортированный список строк:
print(dir(math))
- Функция
help
внутри интерпретатора Python предоставляет информацию об определенной функции в модуле:
help(math.factorial)
Packages
Пакеты — это коллекция модулей, собранных вместе. Базовые пакеты машинного обучения — Numpy и Scipy — состоят из коллекции сотен модулей. Ниже приведен неполный список подпакетов, доступных в SciPy.
Модуль Collections
Collections — это встроенный модуль Python, реализующий специализированный контейнер типов данных. Является альтернативой встроенным контейнерам общего назначения Python, таким как dict
, list
, set
и tuple
.
Рассмотрим несколько структур данных, представленных в этом модуле:
1. namedtuple()
Доступ к данным, хранящимся в обычном кортеже, можно получить с помощью индексов. Пример:
plain_tuple = (10,11,12,13)
plain_tuple[0]
10
plain_tuple[3]
13
Не обязательно давать названия отдельным элементам, хранящимся в кортеже. В этом есть необходимость лишь в том случае, если кортеж обладает множеством полей.
Именно здесь функциональность namedtuple проявляет свои силы. Это функция для кортежей с именованными полями (Named Fields), которую можно рассматривать как расширение встроенного типа данных tuple. Именованные кортежи задают значение для каждой позиции в кортеже, делая код более читаемым и самодокументируемым. Доступ к объектам, хранящимся в кортеже, можно получить с помощью уникального (удобного для чтения) идентификатора. Это избавляет от необходимости запоминать целочисленные индексы. Рассмотрим его реализацию.
from collections import namedtuple
fruit = namedtuple('fruit','number variety color')
guava = fruit(number=2,variety='HoneyCrisp',color='green')
apple = fruit(number=5,variety='Granny Smith',color='red')
Построение namedtuple начинается с передачи названия объекта type (fruit). Затем передается строка с пробелами между названиям каждого поля. Теперь можно обращаться к различным параметрам:
guava.color
'green'
apple.variety
'Granny Smith'
Namedtuples — эффективная для памяти опция при определении неизменяемых полей в Python.
2. Counter
Counter — это подкласс dict, который используется для подсчета объектов hashable. Элементы хранятся в качестве ключей словаря, а количество объектов сохранено в качестве значения. Рассмотрим несколько примеров с Counter.
#Importing Counter from collections
from collections import Counter
- Со строками
c = Counter('abcacdabcacd')
print(c)
Counter({'a': 4, 'c': 4, 'b': 2, 'd': 2})
- Со списками
lst = [5,6,7,1,3,9,9,1,2,5,5,7,7]
c = Counter(lst)
print(c)
Counter({'a': 4, 'c': 4, 'b': 2, 'd': 2})
- С предложением
s = 'the lazy dog jumped over another lazy dog'
words = s.split()
Counter(words)
Counter({'another': 1, 'dog': 2, 'jumped': 1, 'lazy': 2, 'over': 1, 'the': 1})
Помимо доступных для всех словарей методов, объекты Counter поддерживают еще три дополнительных:
- elements()
Возвращает количество каждого элемента. В случае, если количество элемента меньше одного, метод не выполняется.
c = Counter(a=3, b=2, c=1, d=-2)
sorted(c.elements())
['a', 'a', 'a', 'b', 'b', 'c']
- most_common([n])
Возвращает список наиболее повторяемых элементов и количество каждого из них. Количество элементов указывается в значении n. Если ни одно из значений не указано, возвращается количество всех элементов.
s = 'the lazy dog jumped over another lazy dog'
words = s.split()
Counter(words).most_common(3)
[('lazy', 2), ('dog', 2), ('the', 1)]
Распространенные шаблоны использования объекта Counter()
sum(c.values()) # total of all counts
c.clear() # reset all counts
list(c) # list unique elements
set(c) # convert to a set
dict(c) # convert to a regular dictionary c.items() # convert to a list like (elem, cnt)
Counter(dict(list_of_pairs)) # convert from a list of(elem, cnt)
c.most_common()[:-n-1:-1] # n least common elements
c += Counter() # remove zero and negative counts
3. defaultdict
Словари — это эффективный способ хранения данных для дальнейшего извлечения, в котором данные представлены в виде неупорядоченного множества пар key:value. Ключи — это уникальные и неизменяемые объекты.
fruits = {'apple':300, 'guava': 200}
fruits['guava']
200
Все очень просто, когда значения представлены целыми числами или строками. Однако если они представлены в форме списков и словарей, значение (пустой список или словарь) нужно инициализировать при первом использовании ключа. defaultdict автоматизирует и упрощает этот процесс. Для лучшего понимания рассмотрим пример ниже:
d = {}
print(d['A'])
Словарь Python выдает ошибку, поскольку ‘A’ на данный момент не находится в словаре. Рассмотрим тот же самый пример с использованием defaultdict.
from collections import defaultdict
d = defaultdict(object)
print(d['A'])
<object object at 0x7fc9bed4cb00>
defaultdict
создает элементы, для которых нужно получить доступ (если они еще не существуют). defaultdict также является объектом-словарем и содержит те же методы, что и словарь. Разница заключается в том, что он устанавливает первый аргумент (default_factory) в качестве типа данных по умолчанию для словаря.
4.OrderedDict
OrderedDict — это подкласс словаря, в котором хранится порядок добавления ключей. При итерации упорядоченного словаря элементы возвращаются в порядке добавления их ключей. Поскольку упорядоченный словарь запоминает порядок добавления, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:
- обычный словарь
d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
- словарь, отсортированный по ключу
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
- словарь, отсортированный по значению
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
- словарь, отсортированный по длине строки
OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('banana', 3), ('orange', 2)])
Стоит отметить, что в Python 3.6 обычные словари отсортированы по добавлению, т. е. словари запоминают порядок добавления элементов.
Заключение
Модуль Collections также включает и другие полезные типы данных, такие как deque, Chainmap, UserString и т. д. Я рассказал лишь о самых используемых. Для более полного объяснения посмотрите официальную документацию Python.
Перевод статьи Parul Pandey: Python’s Collections Module — High-performance container data types.