collections

Модуль collections содержит оптимизированные реализации нескольких контейнерных типов, абстрактные базовые классы для различных типов контейнеров и вспомогательные функции для создания именованных кортежей.

Также определено несколько абстрактных базовых классов.

Назначение их состоит в том, чтобы описать программный интерфейс некоторых типов контейнеров, таких как списки, множества и словари.

Можно выделить два основных случая использования этих классов.

Во-первых,они могут использоваться, как базовые классы для пользовательских объектов, имитирующих функциональность встроенных контейнерных типов.

Во-вторых, они могут использоваться для проверки типов.

Например, если требуется убедиться, что объект s способен действовать как последовательность, можно вызвать функцию isinstance(s, collections.Sequence).

Соответствующие встроенные типы языка Python уже зарегистрированы в этих базовых классах.

Кроме того, используя эти базовые классы, можно писать программы, которые выполняют более точную проверку типов. Например:

# Получить последний элемент последовательности
if isinstance(x, collections.Sequence):
    last = x[-1]

# Выполнить итерации по объекту, только если известен его размер
if isinstance(x, collections.Iterable) and isinstance(x, collections.Sized):
    for item in x:
        pass

# Добавить новый элемент в множество
if isinstance(x, collections.MutableSet):
    x.add(item)

defaultdict

class collections.defaultdict([default_factory, ]...)

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

Когда происходит обращение к несуществующему ключу, вызывается функция, которая передается в аргументе default_factory. Эта функция должна вернуть значение по умолчанию, которое затем сохраняется как значение указанного ключа.

Остальные аргументы функции defaultdict() в точности те же самые, что передаются встроенной функции dict().

Объекты типа defaultdict удобно использовать в качестве словаря для слежения за данными.

Например, предположим, что необходимо отслеживать позицию каждого слова в строке s. Ниже показано, насколько просто это можно реализовать с помощью объекта defaultdict:

from collections import defaultdict

s = "yeah but no but yeah but no but yeah"
words = s.split()
wordlocations = defaultdict(list)

for n, w in enumerate(words):
    wordlocations[w].append(n)

wordlocations
# defaultdict(<type ‘list’>, {‘yeah’:[0, 4, 8],’but’: [1, 3, 5, 7],’no’: [2, 6]})

В этом примере операция обращения к элементу словаря wordlocations[w] будет «терпеть неудачу», когда слово встречается впервые. Однако вместо исключения KeyError будет вызвана функция list, переданная в аргументе default_factory, которая создаст новое значение.

Встроенные словари имеют метод setdefault(), который позволяет добиться того же эффекта, но его использование делает программный код менее наглядным, и к тому же он работает медленнее.

Например, инструкцию, добавляющую новый элемент в предыдущем примере, можно было бы заменить инструкцией wordlocations.setdefault(w,[]).append(n). Но она не так очевидна и выполняется почти в два раза медленнее, чем пример с использованием объекта defaultdict.

d = defaultdict(lambda : 6)
d["k"] += 1
d['k']
# 7

deque

class collections.deque([iterable[, maxlenght]])
  • iterable - начальное заполнение очереди

  • maxlenght - если передается, то возвращаемый объект deque превращается в кольцевой буфер указанного размера.

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

Тип данных, представляющий двустороннюю очередь (название типа deque произносится «дек»).

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

Реализация очередей оптимизирована так, что эти операции имеют примерно одинаковую производительность (O(1)).

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

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

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

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

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

    Двусторонние очереди поддерживают также возможность сериализации средствами модуля pickle.

from timeit import timeit
timeit(
    's.appendleft(37)',
    'import collections; s = collections.deque()',
    number=1000000)
# 0.24434304237365723

timeit(
    's.insert(0, 37)',
    's = []',
    number=1000000)
# 612.95199513435364

Экземпляры имеют следующие методы

append(x)

Добавляет объект x с правой стороны очереди.

appendleft(x)

Добавляет объект x с левой стороны очереди

clear()

Удаляет все элементы из очереди

extend(iterable)

Расширяет очередь, добавляя с правой стороны все элементы из итерируемого объекта iterable.

extendleft(iterable)

Расширяет очередь, добавляя с левой стороны все элементы из итерируемого объекта iterable.

Из-за того, что добавление производится последовательно, по одному элементу, элементы итерируемого объекта iterable будут добавлены в очередь d в обратном порядке.

pop()

Удаляет и возвращает элемент с правой стороны очереди

Если очередь пуста, возбуждает исключение IndexError.

popleft()

Удаляет и возвращает элемент с левой стороны очереди

Если очередь пуста, возбуждает исключение IndexError.

remove(item)

Удаляет первое вхождение элемента item. Возбуждает исключение ValueError, если указанное значение не будет найдено.

rotate(n)

Прокручивает все элементы на n позиций вправо. Если в аргументе n передается отрицательное значение, прокручивание выполняется влево.

namedtuple

collections.namedtuple(typename, fieldnames[, verbose])

Возвращает именованный кортеж.

Именованные кортежи эффективнее расходуют память и поддерживают различные операции над кортежами, такие как распаковывание элементов (например, если имеется список именованных кортежей, эти кортежи можно будет распаковывать в цикле for, например: for name, shares, price in stockList).

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

  • typename - имя класса, возвращаемого объекта

  • fieldnames - список имен атрибутов в виде строк.

    Имена в этом списке должны быть допустимыми идентификаторами Python. Они не должны начинаться с символа подчеркивания, а порядок их следования определяет порядок следования элементов кортежа, например [‘hostname’, ‘port’].

    Кроме того, допускается передавать строку, такую как ‘hostname port’ или ‘hostname, port’.

  • verbose - булево, выводить определение класса в поток стандартного вывода.

from collections import namedtuple

NetworkAddress = namedtuple('NetworkAddress', ['hostname', 'port'])
a = NetworkAddress('www.python.org', 80)

a.hostname
# 'www.python.org'

a.port
# 80

host, port = a
len(a)
# 2

type(a)
# <class ‘__main__.NetworkAddress’>

isinstance(a, tuple)
# True
collections._replace(**kwargs)

Заменяет указанные свойства и возвращает новый объект

Callable

class collections.Callable

Базовый класс объектов, поддерживающих возможность вызова, как функции.

Определяет абстрактный метод __call__().

Container

class collections.Container

Базовый класс всех контейнеров.

Определяет единственный абстрактный метод __contains__(), реализующий оператор in.

Counter

Счетчик

class collections.Counter
counter = Counter(['spam', 'spam', 'eggs', 'spam'])
# Counter({'spam': 3, 'eggs': 1})

counter2 = Counter(['eggs', 'eggs', 'bacon'])
# Counter({'eggs': 2, 'bacon': 1})

counter + counter2
# Counter({'bacon': 1, 'eggs': 3, 'spam': 3})

counter2 - counter
# Counter({'bacon': 1, 'eggs': 1})

counter & counter2
# Counter({'eggs': 1})

counter | counter2
# Counter({'bacon': 1, 'eggs': 2, 'spam': 3})
most_common([count])

Возвращает список всех элементов в убывающем порядке или только те количесвто которых больше указанного аргумента

counter.most_common(1)
# [('spam', 3)]

Hashable

class collections.Hashable

Базовый класс всех объектов, которые могут использоваться в качестве ключей хеш-таблиц.

Определяет единственный абстрактный метод __hash__().

ItemsView

class collections.ItemsView

Базовый класс представления элементов отображения.

Наследует классы MappingView и Set.

Iterable

class collections.Iterable

Базовый класс объектов, поддерживающих протокол итераций.

Определяет единственный абстрактный метод __iter__().

Iterator

class collections.Iterator

Базовый класс итерируемых объектов.

Определяет абстрактный метод next(), а также наследует класс Iterable и предоставляет реализацию по умолчанию метода __iter__(), который просто ничего не делает.

KeysView

class collections.KeysView

Базовый класс представления ключей отображения.

Наследует классы MappingView и Set.

Mapping

class collections.Mapping

Базовый класс объектов, поддерживающих возможность отображения (словари).

Наследует классы Sized, Iterable и Container и определяет абстрактные методы __getitem__(), __len__() и __iter__().

Предоставляет реализацию по умолчанию методов __contains__(), keys(), items(), values(), get(), __eq__() и __ne__().

MappingView

class collections.MappingView

Базовый класс представлений отображений.

Представление отображения – это объект, который позволяет обращаться к элементам объекта отображения как к множествам.

Например, представлением ключей является объект, напоминающий множество, который содержит ключи, имеющиеся в отображении.

MutableMapping

class collections.MutableMapping

Базовый класс изменяемых объектов отображений.

Наследует класс Mapping и добавляет абстрактные методы __setitem__() и __delitem__().

Кроме того, предоставляет реализацию по умолчанию методов pop(), popitem(), clear(), update() и setdefault().

MutableSequence

class collections.MutableSequence

Базовый класс изменяемых последовательностей.

Наследует класс Sequence и добавляет абстрактные методы __setitem__() и __delitem__().

Кроме того, предоставляет реализацию по умолчанию методов append(), reverse(), extend(), pop(), remove() и __iadd__().

MutableSet

class collections.MutableSet

Базовый класс изменяемых множеств.

Наследует класс Set и добавляет абстрактные методы add() и discard().

Кроме того, предоставляет реализацию по умолчанию методов clear(), pop(), remove(), __ior__(), __iand__(), __ixor__ () и __isub__().

OrderedDict

class collections.OrderedDict

Сортированный словарь

quotes = OrderedDict([
    ('key1', 'value1'),
    ('key2', 'value2'),
])

Sequence

class collections.Sequence

Базовый класс объектов, которые выглядят как последовательности.

Наследует классы Container, Iterable и Sized, а также определяет абстрактные методы __getitem__() и __len__().

Кроме того, предоставляет реализацию по умолчанию методов __contains__(), __iter__(), __reversed__(), index() и count(), которые реализованы исключительно посредством методов __getitem__() и __len__().

Set

class collections.Set

Базовый класс объектов, которые действуют как множества.

Наследует классы Container, Iterable и Sized и определяет абстрактные методы __len__(), __iter__() и __contains__().

Кроме того, предоставляет реализацию по умолчанию операций над множествами __le__(), __lt__(), __eq__(), __ne__(), __gt__(), __ge__(), __and__(), __or__(), __xor__(), __sub__() и isdisjoint().

Sized

class collections.Sized

Базовый класс контейнеров, которые позволяют определить размер.

Определяет абстрактный метод __len__().

ValuesView

class collections.ValuesView

Базовый класс представления пар (key, item) отображения.

Наследует классы MappingView и Set.