Документация Python неофициальный перевод

collections.md

882 строк · 72.9 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.2/library/collections.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 7.3. [`collections`](https://python-all.ru/3.2/library/collections.html#module-collections) – Типы данных-контейнеры89**Исходный код:** [Lib/collections.py](https://python-all.ru/src/3.2/Lib/collections.py) и [Lib/\_abcoll.py](https://python-all.ru/src/3.2/Lib/_abcoll.py)1011---1213Этот модуль реализует специализированные типы контейнеров, которые служат альтернативой встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.2/library/functions.html#list), [`set`](https://python-all.ru/3.2/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.2/library/functions.html#tuple).1415| [`namedtuple()`](https://python-all.ru/3.2/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями |16| --- | --- |17| [`deque`](https://python-all.ru/3.2/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов |18| [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов |19| [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей |20| [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений |21| [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict) | обёртка вокруг словарей для упрощения создания подклассов dict |22| [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList) | обёртка вокруг списков для упрощения создания подклассов list |23| [`UserString`](https://python-all.ru/3.2/library/collections.html#collections.UserString) | обёртка вокруг строк для упрощения создания подклассов str |2425В дополнение к конкретным классам-контейнерам, модуль collections предоставляет [*абстрактные базовые классы*](https://python-all.ru/3.2/library/collections.html#collections-abstract-base-classes), которые можно использовать для проверки того, предоставляет ли класс определённый интерфейс, например, является ли он хешируемым или отображением.2627## 7.3.1. [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) объекты2829Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:3031```python32>>> # Подсчитать вхождения слов в списке33>>> cnt = Counter()34>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:35...     cnt[word] += 136>>> cnt37Counter({'blue': 3, 'red': 2, 'green': 1})3839>>> # Найти десять самых распространённых слов в «Гамлете»40>>> import re41>>> words = re.findall('\w+', open('hamlet.txt').read().lower())42>>> Counter(words).most_common(10)43[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),44 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]45```4647#### `class collections.Counter([iterable-or-mapping])`4849[`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) – это подкласс [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict) для подсчёта хешируемых объектов. Это неупорядоченная коллекция, в которой элементы хранятся как ключи словаря, а их количества – как значения словаря. Количества могут быть любыми целыми числами, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) аналогичен мультимножествам (bags или multisets) в других языках.5051Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):5253```python54>>> c = Counter()                           # новый пустой счётчик55>>> c = Counter('gallahad')                 # новый счётчик из итерируемого объекта56>>> c = Counter({'red': 4, 'blue': 2})      # новый счётчик из отображения57>>> c = Counter(cats=4, dogs=8)             # новый счётчик из именованных аргументов58```5960Объекты Counter имеют интерфейс словаря, за исключением того, что при отсутствии элемента они возвращают нулевой счёт вместо возбуждения [`KeyError`](https://python-all.ru/3.2/library/exceptions.html#KeyError):6162```python63>>> c = Counter(['eggs', 'ham'])64>>> c['bacon']                              # счёт отсутствующего элемента равен нулю65066```6768Установка счёта в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:6970```python71>>> c['sausage'] = 0                        # запись счётчика с нулевым значением72>>> del c['sausage']                        # del действительно удаляет запись73```7475Новое в версии 3.1.7677Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:7879#### `elements()`8081Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его счёте. Элементы возвращаются в произвольном порядке. Если счёт элемента меньше единицы, [`elements()`](https://python-all.ru/3.2/library/collections.html#collections.Counter.elements) игнорирует его.8283```python84>>> c = Counter(a=4, b=2, c=0, d=-2)85>>> list(c.elements())86['a', 'a', 'a', 'a', 'b', 'b']87```8889#### `most_common([n])`9091Возвращает список из *n* наиболее часто встречающихся элементов и их количество, от самого частого к самому редкому. Если *n* не указан, [`most_common()`](https://python-all.ru/3.2/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковым количеством упорядочиваются произвольно:9293```python94>>> Counter('abracadabra').most_common(3)95[('a', 5), ('r', 2), ('b', 2)]96```9798#### `subtract([iterable-or-mapping])`99100Элементы вычитаются из *iterable* или из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.2/library/stdtypes.html#dict.update), но вычитает счёты вместо их замены. И входные, и выходные значения могут быть нулевыми или отрицательными.101102```python103>>> c = Counter(a=4, b=2, c=0, d=-2)104>>> d = Counter(a=1, b=2, c=3, d=4)105>>> c.subtract(d)106>>> c107Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})108```109110Новое в версии 3.2.111112Для объектов [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) доступны обычные методы словаря, за исключением двух, которые работают иначе для счётчиков.113114#### `fromkeys(iterable)`115116Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter).117118#### `update([iterable-or-mapping])`119120Элементы подсчитываются из *iterable* или добавляются из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.2/library/stdtypes.html#dict.update), но добавляет счёты вместо их замены. Кроме того, *iterable* должен быть последовательностью элементов, а не последовательностью пар `(key, value)`.121122Распространённые приёмы работы с объектами [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter):123124```python125sum(c.values())                 # сумма всех значений126c.clear()                       # сбросить все значения127list(c)                         # список уникальных элементов128set(c)                          # преобразовать в множество129dict(c)                         # преобразовать в обычный словарь130c.items()                       # преобразовать в список пар (elem, cnt)131Counter(dict(list_of_pairs))    # создать из списка пар (элемент, кол-во)132c.most_common()[:-n:-1]         # n наименее частых элементов133c += Counter()                  # удалить нулевые и отрицательные значения134```135136Для объединения объектов [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) в мультимножества (счётчики, в которых счёты больше нуля) предусмотрено несколько математических операций. Сложение и вычитание объединяют счётчики путём сложения или вычитания счётов соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих счётов. Каждая операция может принимать входные данные со знаковыми счётами, но на выходе будут исключены результаты со счётом ноль или меньше.137138```python139>>> c = Counter(a=3, b=1)140>>> d = Counter(a=1, b=2)141>>> c + d                       # сложение двух счётчиков: c[x] + d[x]142Counter({'a': 4, 'b': 3})143>>> c - d                       # вычитание (остаются только положительные значения)144Counter({'a': 2})145>>> c & d                       # пересечение: min(c[x], d[x])146Counter({'a': 1, 'b': 1})147>>> c | d                       # объединение: max(c[x], d[x])148Counter({'a': 3, 'b': 2})149```150151> **Примечание**152>153> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.154>155> - Сам класс [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения предназначены для чисел, представляющих счёты, но в поле значения *можно* хранить что угодно.156> - Метод `most_common()` требует только, чтобы значения были упорядочиваемыми.157> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа подойдут, а отрицательные значения поддерживаются. То же самое верно для `update()` и `subtract()`, которые допускают отрицательные и нулевые значения как на входе, так и на выходе.158> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.159> - Метод `elements()` требует целочисленных счётов. Он игнорирует нулевые и отрицательные счёты.160161> **См. также**162>163> - [Класс Counter](https://python-all.ru/3.2/library/collections.html) адаптирован для Python 2.5 и раннего [рецепта Bag](https://python-all.ru/3.2/library/collections.html) для Python 2.4.164> - [Класс Bag](https://python-all.ru/3.2/library/collections.html) в Smalltalk.165> - Статья в Википедии о [мультимножествах](https://python-all.ru/3.2/library/collections.html).166> - [Мультимножества в C++](https://python-all.ru/3.2/library/collections.html): учебное пособие с примерами.167> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.168> - Чтобы перечислить все различные мультимножества заданного размера из заданного набора элементов, см. [`itertools.combinations_with_replacement()`](https://python-all.ru/3.2/library/itertools.html#itertools.combinations_with_replacement).169>170>   > map(Counter, combinations\_with\_replacement(‘ABC’, 2)) –\> AA AB AC BB BC CC171172## 7.3.2. [`deque`](https://python-all.ru/3.2/library/collections.html#collections.deque) объекты173174#### `class collections.deque([iterable[, maxlen]])`175176Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.2/library/collections.html#collections.deque.append)) данными из *iterable*. Если *iterable* не указан, новый deque пуст.177178Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.179180Хотя объекты [`list`](https://python-all.ru/3.2/library/functions.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и несут затраты памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.181182Если *maxlen* не указан или равен *None*, deque могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque с ограниченной длиной заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.183184Объекты deque поддерживают следующие методы:185186#### `append(x)`187188Добавляет *x* в правую часть deque.189190#### `appendleft(x)`191192Добавляет *x* в левую часть deque.193194#### `clear()`195196Удаляет все элементы из deque, после чего его длина равна 0.197198#### `count(x)`199200Подсчитывает количество элементов deque, равных *x*.201202Новое в версии 3.2.203204#### `extend(iterable)`205206Расширяет правую часть deque, добавляя элементы из итерируемого объекта.207208#### `extendleft(iterable)`209210Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.211212#### `pop()`213214Удаляет и возвращает элемент с правой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.2/library/exceptions.html#IndexError).215216#### `popleft()`217218Удаляет и возвращает элемент с левой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.2/library/exceptions.html#IndexError).219220#### `remove(value)`221222Удаляет первое вхождение *value*. Если не найдено, возбуждает [`ValueError`](https://python-all.ru/3.2/library/exceptions.html#ValueError).223224#### `reverse()`225226Переворачивает элементы deque по месту и затем возвращает `None`.227228Новое в версии 3.2.229230#### `rotate(n)`231232Поворачивает deque на *n* шагов вправо. Если *n* отрицательно, поворачивает влево. Поворот на один шаг вправо эквивалентен: `d.appendleft(d.pop())`.233234Объекты deque также предоставляют один атрибут только для чтения:235236#### `maxlen`237238Максимальный размер deque или *None*, если неограничен.239240Новое в версии 3.1.241242В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.2/reference/expressions.html#in) и доступ по индексу, например `d[-1]`. Индексированный доступ занимает O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.243244Пример:245246```python247>>> from collections import deque248>>> d = deque('ghi')                 # создать новый deque с тремя элементами249>>> for elem in d:                   # обход элементов deque250...     print(elem.upper())251G252H253I254255>>> d.append('j')                    # добавить новый элемент справа256>>> d.appendleft('f')                # добавить новый элемент слева257>>> d                                # показать представление deque258deque(['f', 'g', 'h', 'i', 'j'])259260>>> d.pop()                          # вернуть и удалить правый элемент261'j'262>>> d.popleft()                      # вернуть и удалить левый элемент263'f'264>>> list(d)                          # вывести содержимое deque265['g', 'h', 'i']266>>> d[0]                             # посмотреть левый элемент267'g'268>>> d[-1]                            # посмотреть правый элемент269'i'270271>>> list(reversed(d))                # вывести содержимое deque в обратном порядке272['i', 'h', 'g']273>>> 'h' in d                         # поиск в deque274True275>>> d.extend('jkl')                  # добавить несколько элементов за раз276>>> d277deque(['g', 'h', 'i', 'j', 'k', 'l'])278>>> d.rotate(1)                      # поворот вправо279>>> d280deque(['l', 'g', 'h', 'i', 'j', 'k'])281>>> d.rotate(-1)                     # поворот влево282>>> d283deque(['g', 'h', 'i', 'j', 'k', 'l'])284285>>> deque(reversed(d))               # создать новую deque в обратном порядке286deque(['l', 'k', 'j', 'i', 'h', 'g'])287>>> d.clear()                        # очистить deque288>>> d.pop()                          # невозможно извлечь элемент из пустой deque289Traceback (most recent call last):290  File "<pyshell#6>", line 1, in -toplevel-291    d.pop()292IndexError: pop from an empty deque293294>>> d.extendleft('abc')              # extendleft() меняет порядок ввода на обратный295>>> d296deque(['c', 'b', 'a'])297```298299### 7.3.2.1. [`deque`](https://python-all.ru/3.2/library/collections.html#collections.deque) Рецепты300301В этом разделе рассматриваются различные подходы к работе с деками.302303Двусторонние очереди с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:304305```python306def tail(filename, n=10):307    'Return the last n lines of a file'308    return deque(open(filename), n)309```310311Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:312313```python314def moving_average(iterable, n=3):315    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0316    # http://en.wikipedia.org/wiki/Moving_average317    it = iter(iterable)318    d = deque(itertools.islice(it, n-1))319    d.appendleft(0)320    s = sum(d)321    for elem in it:322        s += elem - d.popleft()323        d.append(elem)324        yield s / n325```326327Метод `rotate()` предоставляет способ реализовать срезы и удаление для [`deque`](https://python-all.ru/3.2/library/collections.html#collections.deque). Например, чистая реализация Python для `del d[n]` опирается на метод `rotate()` для позиционирования элементов, которые нужно извлечь:328329```python330def delete_nth(d, n):331    d.rotate(-n)332    d.popleft()333    d.rotate(n)334```335336Чтобы реализовать срезы для [`deque`](https://python-all.ru/3.2/library/collections.html#collections.deque), используйте аналогичный подход, применяя `rotate()` для перемещения целевого элемента к левой стороне deque. Удалите старые записи с помощью `popleft()`, добавьте новые с помощью `extend()`, а затем обратите вращение. С небольшими вариациями этого подхода легко реализовать стековые манипуляции в стиле Forth, такие как `dup`, `drop`, `swap`, `over`, `pick`, `rot` и `roll`.337338## 7.3.3. [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) объекты339340#### `class collections.defaultdict([default_factory[, ...]])`341342Возвращает новый объект, подобный словарю. [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict), и здесь не документируется.343344Первый аргумент задаёт начальное значение для атрибута [`default_factory`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.default_factory); по умолчанию `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict), включая именованные аргументы.345346Объекты [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict):347348#### `__missing__(key)`349350Если атрибут [`default_factory`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.default_factory) равен `None`, это возбуждает исключение [`KeyError`](https://python-all.ru/3.2/library/exceptions.html#KeyError) с *key* в качестве аргумента.351352Если [`default_factory`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов, чтобы предоставить значение по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.353354Если вызов [`default_factory`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.default_factory) возбуждает исключение, это исключение распространяется без изменений.355356Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict), когда запрошенный ключ не найден; то, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getitem__).357358Обратите внимание, что [`__missing__()`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.__missing__) *не* вызывается для любых операций, кроме [`__getitem__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__getitem__). Это означает, что `get()`, как и обычные словари, будет возвращать `None` в качестве значения по умолчанию, а не использовать [`default_factory`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.default_factory).359360Объекты [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) поддерживают следующую переменную экземпляра:361362#### `default_factory`363364Этот атрибут используется методом [`__missing__()`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он присутствует, или `None`, если отсутствует.365366### 7.3.3.1. [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) Примеры367368Используя [`list`](https://python-all.ru/3.2/library/functions.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:369370```python371>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]372>>> d = defaultdict(list)373>>> for k, v in s:374...     d[k].append(v)375...376>>> list(d.items())377[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]378```379380Когда ключ встречается впервые, его ещё нет в отображении; поэтому запись автоматически создаётся с помощью функции `default_factory`, которая возвращает пустой [`list`](https://python-all.ru/3.2/library/functions.html#list). Затем операция `list.append()` добавляет значение в новый список. При повторной встрече ключа поиск происходит обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет ещё одно значение в список. Этот метод проще и быстрее, чем эквивалентный приём с [`dict.setdefault()`](https://python-all.ru/3.2/library/stdtypes.html#dict.setdefault):381382```python383>>> d = {}384>>> for k, v in s:385...     d.setdefault(k, []).append(v)386...387>>> list(d.items())388[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]389```390391Установка `default_factory` в [`int`](https://python-all.ru/3.2/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) полезным для подсчёта (как мешок или мультимножество в других языках):392393```python394>>> s = 'mississippi'395>>> d = defaultdict(int)396>>> for k in s:397...     d[k] += 1398...399>>> list(d.items())400[('i', 4), ('p', 2), ('s', 4), ('m', 1)]401```402403Когда буква встречается впервые, она отсутствует в отображении, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.2/library/functions.html#int), чтобы получить нулевое значение по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.404405Функция [`int()`](https://python-all.ru/3.2/library/functions.html#int), которая всегда возвращает ноль, – всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):406407```python408>>> def constant_factory(value):409...     return lambda: value410>>> d = defaultdict(constant_factory('<missing>'))411>>> d.update(name='John', action='ran')412>>> '%(name)s %(action)s to %(object)s' % d413'John ran to <missing>'414```415416Установка `default_factory` в [`set`](https://python-all.ru/3.2/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.2/library/collections.html#collections.defaultdict) полезным для построения словаря множеств:417418```python419>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]420>>> d = defaultdict(set)421>>> for k, v in s:422...     d[k].add(v)423...424>>> list(d.items())425[('blue', set([2, 4])), ('red', set([1, 3]))]426```427428## 7.3.4. [`namedtuple()`](https://python-all.ru/3.2/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями429430Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.431432#### `collections.namedtuple(typename, field_names, verbose=False, rename=False)`433434Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежу, поля которых доступны через обращение к атрибутам, а также индексируемы и итерируемы. Экземпляры подкласса также имеют полезную docstring (с именем типа и полями) и полезный метод [`__repr__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.435436Параметр *field\_names* может быть строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`. Как вариант, *field\_names* может быть последовательностью строк, например `['x', 'y']`.437438В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и подчёркиваний, но не начинаются с цифры или подчёркивания и не могут быть [`ключевым словом`](https://python-all.ru/3.2/library/keyword.html#module-keyword), таким как *class*, *for*, *return*, *global*, *pass* или *raise*.439440Если *rename* равно true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, удаляя ключевое слово `def` и дублирующееся имя поля `abc`.441442Если *verbose* равно true, определение класса выводится непосредственно перед его созданием.443444Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.445446Изменено в версии 3.1: Добавлена поддержка *rename*.447448```python449>>> # Базовый пример450>>> Point = namedtuple('Point', ['x', 'y'])451>>> p = Point(x=10, y=11)452453>>> # Пример использования опции verbose для вывода определения класса454>>> Point = namedtuple('Point', 'x y', verbose=True)455class Point(tuple):456        'Point(x, y)'457458        __slots__ = ()459460        _fields = ('x', 'y')461462        def __new__(_cls, x, y):463            'Create a new instance of Point(x, y)'464            return _tuple.__new__(_cls, (x, y))465466        @classmethod467        def _make(cls, iterable, new=tuple.__new__, len=len):468            'Make a new Point object from a sequence or iterable'469            result = new(cls, iterable)470            if len(result) != 2:471                raise TypeError('Expected 2 arguments, got %d' % len(result))472            return result473474        def __repr__(self):475            'Return a nicely formatted representation string'476            return self.__class__.__name__ + '(x=%r, y=%r)' % self477478        def _asdict(self):479            'Return a new OrderedDict which maps field names to their values'480            return OrderedDict(zip(self._fields, self))481482        __dict__ = property(_asdict)483484        def _replace(_self, **kwds):485            'Return a new Point object replacing specified fields with new values'486            result = _self._make(map(kwds.pop, ('x', 'y'), _self))487            if kwds:488                raise ValueError('Got unexpected field names: %r' % list(kwds.keys()))489            return result490491        def __getnewargs__(self):492            'Return self as a plain tuple.   Used by copy and pickle.'493            return tuple(self)494495        x = _property(_itemgetter(0), doc='Alias for field number 0')496        y = _property(_itemgetter(1), doc='Alias for field number 1')497498>>> p = Point(11, y=22)     # создать экземпляр с позиционными или именованными аргументами499>>> p[0] + p[1]             # доступен по индексу, как обычный кортеж (11, 22)50033501>>> x, y = p                # распаковывается как обычный кортеж502>>> x, y503(11, 22)504>>> p.x + p.y               # поля также доступны по имени50533506>>> p                       # читаемое __repr__ в стиле name=value507Point(x=11, y=22)508```509510Именованные кортежи особенно полезны для присвоения имён полям кортежам результатов, возвращаемым модулями [`csv`](https://python-all.ru/3.2/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.2/library/sqlite3.html#module-sqlite3):511512```python513EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')514515import csv516for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):517    print(emp.name, emp.title)518519import sqlite3520conn = sqlite3.connect('/companydata')521cursor = conn.cursor()522cursor.execute('SELECT name, age, title, department, paygrade FROM employees')523for emp in map(EmployeeRecord._make, cursor.fetchall()):524    print(emp.name, emp.title)525```526527В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и один атрибут. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.528529#### `classmethod somenamedtuple._make(iterable)`530531Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.532533```python534>>> t = [11, 22]535>>> Point._make(t)536Point(x=11, y=22)537```538539#### `somenamedtuple._asdict()`540541Возвращает новый [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict), который сопоставляет имена полей с соответствующими значениями:542543```python544>>> p._asdict()545OrderedDict([('x', 11), ('y', 22)])546```547548Изменено в версии 3.1: Возвращает [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict).549550#### `somenamedtuple._replace(kwargs)`551552Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:553554```python555>>> p = Point(x=11, y=22)556>>> p._replace(x=33)557Point(x=33, y=22)558559>>> for partnum, record in inventory.items():560...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())561```562563#### `somenamedtuple._fields`564565Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.566567```python568>>> p._fields            # просмотреть имена полей569('x', 'y')570571>>> Color = namedtuple('Color', 'red green blue')572>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)573>>> Pixel(11, 22, 128, 255, 0)574Pixel(x=11, y=22, red=128, green=255, blue=0)575```576577Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.2/library/functions.html#getattr):578579```python580>>> getattr(p, 'x')58111582```583584Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [*Распаковка списков аргументов*](https://python-all.ru/3.2/tutorial/controlflow.html#tut-unpacking-arguments)):585586```python587>>> d = {'x': 11, 'y': 22}588>>> Point(**d)589Point(x=11, y=22)590```591592Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:593594```python595>>> class Point(namedtuple('Point', 'x y')):596        __slots__ = ()597        @property598        def hypot(self):599            return (self.x ** 2 + self.y ** 2) ** 0.5600        def __str__(self):601            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)602```603604```python605>>> for p in Point(3, 4), Point(14, 5/7):606        print(p)607Point: x= 3.000  y= 4.000  hypot= 5.000608Point: x=14.000  y= 0.714  hypot=14.018609```610611Приведённый выше подкласс устанавливает `__slots__` в пустой кортеж. Это помогает снизить потребление памяти, предотвращая создание словарей экземпляров.612613Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа на основе атрибута `_fields`:614615```python616>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))617```618619Значения по умолчанию можно реализовать, используя `_replace()` для настройки экземпляра-прототипа:620621```python622>>> Account = namedtuple('Account', 'owner balance transaction_count')623>>> default_account = Account('<owner name>', 0.0, 0)624>>> johns_account = default_account._replace(owner='John')625```626627Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простое объявление класса:628629```python630>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))631>>> Status.open, Status.pending, Status.closed632(0, 1, 2)633>>> class Status:634        open, pending, closed = range(3)635```636637> **См. также**638>639> - [Рецепт именованного кортежа](https://python-all.ru/3.2/library/collections.html) адаптирован для Python 2.4.640> - [Рецепт абстрактного базового класса именованного кортежа с примесью метакласса](https://python-all.ru/3.2/library/collections.html) от Яна Калишевского. Кроме предоставления [*абстрактного базового класса*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class) для именованных кортежей, он также поддерживает альтернативный конструктор на основе [*метакласса*](https://python-all.ru/3.2/glossary.html#term-metaclass), что удобно для случаев, когда именованные кортежи наследуются.641642## 7.3.5. [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) объекты643644Упорядоченные словари работают как обычные словари, но запоминают порядок, в котором были добавлены элементы. При итерации по упорядоченному словарю элементы возвращаются в том порядке, в котором их ключи были впервые добавлены.645646#### `class collections.OrderedDict([items])`647648Возвращает экземпляр подкласса dict, поддерживающий обычные методы [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict). *OrderedDict* – это словарь, который запоминает порядок, в котором ключи были вставлены впервые. Если новая запись перезаписывает существующую, исходная позиция вставки остаётся неизменной. Удаление записи и повторная вставка перемещает её в конец.649650Новое в версии 3.1.651652#### `popitem(last=True)`653654Метод [`popitem()`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (ключ, значение). Пары возвращаются в порядке LIFO, если *last* равно true, или в порядке FIFO, если false.655656#### `move_to_end(key, last=True)`657658Перемещает существующий *ключ* на любой конец упорядоченного словаря. Элемент перемещается в правый конец, если *last* равно true (по умолчанию), или в начало, если *last* равно false. Возбуждает [`KeyError`](https://python-all.ru/3.2/library/exceptions.html#KeyError), если *ключ* не существует:659660```python661>>> d = OrderedDict.fromkeys('abcde')662>>> d.move_to_end('b')663>>> ''.join(d.keys())664'acdeb'665>>> d.move_to_end('b', last=False)666>>> ''.join(d.keys())667'bacde'668```669670Новое в версии 3.2.671672В дополнение к обычным методам отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.2/library/functions.html#reversed).673674Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) учитывают порядок и реализуются как `list(od1.items())==list(od2.items())`. Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/3.2/library/collections.html#collections.Mapping) не учитывают порядок, как обычные словари. Это позволяет заменять объекты [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) везде, где используется обычный словарь.675676Конструктор [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) и метод `update()` оба принимают именованные аргументы, но их порядок теряется, поскольку семантика вызова функций Python передаёт именованные аргументы с помощью обычного неупорядоченного словаря.677678> **См. также**679>680> [Эквивалентный рецепт OrderedDict](https://python-all.ru/3.2/library/collections.html) , работающий на Python 2.4 или новее.681682### 7.3.5.1. [`OrderedDict`](https://python-all.ru/3.2/library/collections.html#collections.OrderedDict) Примеры и рецепты683684Поскольку упорядоченный словарь запоминает порядок вставки, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:685686```python687>>> # обычный неотсортированный словарь688>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}689690>>> # словарь, отсортированный по ключу691>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))692OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])693694>>> # словарь, отсортированный по значению695>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))696OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])697698>>> # словарь, отсортированный по длине строки ключа699>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))700OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])701```702703Новые отсортированные словари сохраняют порядок сортировки при удалении записей. Но при добавлении новых ключей они добавляются в конец, и сортировка не сохраняется.704705Также несложно создать вариант упорядоченного словаря, который запоминает порядок, в котором ключи были *в последний раз* вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки меняется и перемещается в конец:706707```python708class LastUpdatedOrderedDict(OrderedDict):709    'Store items in the order the keys were last added'710711    def __setitem__(self, key, value):712        if key in self:713            del self[key]714        OrderedDict.__setitem__(self, key, value)715```716717Упорядоченный словарь можно комбинировать с классом [`Counter`](https://python-all.ru/3.2/library/collections.html#collections.Counter), чтобы счётчик запоминал порядок, в котором элементы встретились впервые:718719```python720class OrderedCounter(Counter, OrderedDict):721     'Counter that remembers the order elements are first encountered'722723     def __repr__(self):724         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))725726     def __reduce__(self):727         return self.__class__, (OrderedDict(self),)728```729730## 7.3.6. [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict) объекты731732Класс [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов словаря. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`dict`](https://python-all.ru/3.2/library/stdtypes.html#dict); однако с этим классом может быть проще работать, потому что базовый словарь доступен как атрибут.733734#### `class collections.UserDict([initialdata])`735736Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, который доступен через атрибут [`data`](https://python-all.ru/3.2/library/collections.html#collections.UserDict.data) объектов [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict). Если передан *initialdata*, то [`data`](https://python-all.ru/3.2/library/collections.html#collections.UserDict.data) инициализируется его содержимым; обратите внимание, что ссылка на *initialdata* не сохраняется, что позволяет использовать его для других целей.737738В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict) предоставляют следующий атрибут:739740#### `data`741742Настоящий словарь, используемый для хранения содержимого класса [`UserDict`](https://python-all.ru/3.2/library/collections.html#collections.UserDict).743744## 7.3.7. [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList) объекты745746Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.747748Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`list`](https://python-all.ru/3.2/library/functions.html#list); однако с этим классом может быть проще работать, потому что базовый список доступен как атрибут.749750#### `class collections.UserList([list])`751752Класс, имитирующий список. Содержимое экземпляра хранится в обычном списке, который доступен через атрибут [`data`](https://python-all.ru/3.2/library/collections.html#collections.UserList.data) объектов [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList). Содержимое экземпляра изначально устанавливается в копию *list*, по умолчанию пустой список `[]`. *list* может быть любым итерируемым объектом, например, настоящим списком Python или объектом [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList).753754В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList) предоставляют следующий атрибут:755756#### `data`757758Настоящий объект [`list`](https://python-all.ru/3.2/library/functions.html#list), используемый для хранения содержимого класса [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList).759760**Требования к наследованию:** Подклассы [`UserList`](https://python-all.ru/3.2/library/collections.html#collections.UserList) должны предоставлять конструктор, который можно вызывать без аргументов или с одним аргументом. Операции со списками, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром, который является объектом последовательности, используемым в качестве источника данных.761762Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.763764## 7.3.8. [`UserString`](https://python-all.ru/3.2/library/collections.html#collections.UserString) объекты765766Класс [`UserString`](https://python-all.ru/3.2/library/collections.html#collections.UserString) действует как обёртка вокруг строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`str`](https://python-all.ru/3.2/library/functions.html#str); однако с этим классом может быть проще работать, потому что базовая строка доступна как атрибут.767768#### `class collections.UserString([sequence])`769770Класс, имитирующий строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, который доступен через атрибут `data` объектов [`UserString`](https://python-all.ru/3.2/library/collections.html#collections.UserString). Содержимое экземпляра изначально устанавливается в копию *sequence*. *sequence* может быть экземпляром [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes), [`str`](https://python-all.ru/3.2/library/functions.html#str), [`UserString`](https://python-all.ru/3.2/library/collections.html#collections.UserString) (или подклассом) или произвольной последовательностью, которая может быть преобразована в строку с помощью встроенной функции [`str()`](https://python-all.ru/3.2/library/functions.html#str).771772## 7.3.9. ABCs - абстрактные базовые классы773774Модуль collections предоставляет следующие [*абстрактные базовые классы*](https://python-all.ru/3.2/glossary.html#term-abstract-base-class):775776| ABC | Наследует от | Абстрактные методы | Методы-примеси |777| --- | --- | --- | --- |778| [`Container`](https://python-all.ru/3.2/library/collections.html#collections.Container) |  | `__contains__` |  |779| [`Hashable`](https://python-all.ru/3.2/library/collections.html#collections.Hashable) |  | `__hash__` |  |780| [`Iterable`](https://python-all.ru/3.2/library/collections.html#collections.Iterable) |  | `__iter__` |  |781| [`Iterator`](https://python-all.ru/3.2/library/collections.html#collections.Iterator) | [`Iterable`](https://python-all.ru/3.2/library/collections.html#collections.Iterable) | `__next__` | `__iter__` |782| [`Sized`](https://python-all.ru/3.2/library/collections.html#collections.Sized) |  | `__len__` |  |783| [`Callable`](https://python-all.ru/3.2/library/collections.html#collections.Callable) |  | `__call__` |  |784| [`Sequence`](https://python-all.ru/3.2/library/collections.html#collections.Sequence) | [`Sized`](https://python-all.ru/3.2/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/3.2/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/3.2/library/collections.html#collections.Container) | `__getitem__` | `__contains__`, `__iter__`, `__reversed__`, `index` и `count` |785| [`MutableSequence`](https://python-all.ru/3.2/library/collections.html#collections.MutableSequence) | [`Sequence`](https://python-all.ru/3.2/library/collections.html#collections.Sequence) | `__setitem__`, `__delitem__`, `insert` | Унаследованные методы [`Sequence`](https://python-all.ru/3.2/library/collections.html#collections.Sequence) и `append`, `reverse`, `extend`, `pop`, `remove` и `__iadd__` |786| [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) | [`Sized`](https://python-all.ru/3.2/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/3.2/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/3.2/library/collections.html#collections.Container) |  | `__le__`, `__lt__`, `__eq__`, `__ne__`, `__gt__`, `__ge__`, `__and__`, `__or__`, `__sub__`, `__xor__` и `isdisjoint` |787| [`MutableSet`](https://python-all.ru/3.2/library/collections.html#collections.MutableSet) | [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) | `add`, `discard` | Унаследованные [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) методы и `clear`, `pop`, `remove`, `__ior__`, `__iand__`, `__ixor__` и `__isub__` |788| [`Mapping`](https://python-all.ru/3.2/library/collections.html#collections.Mapping) | [`Sized`](https://python-all.ru/3.2/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/3.2/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/3.2/library/collections.html#collections.Container) | `__getitem__` | `__contains__`, `keys`, `items`, `values`, `get`, `__eq__` и `__ne__` |789| [`MutableMapping`](https://python-all.ru/3.2/library/collections.html#collections.MutableMapping) | [`Mapping`](https://python-all.ru/3.2/library/collections.html#collections.Mapping) | `__setitem__`, `__delitem__` | Унаследованные [`Mapping`](https://python-all.ru/3.2/library/collections.html#collections.Mapping) методы и `pop`, `popitem`, `clear`, `update`, и `setdefault` |790| [`MappingView`](https://python-all.ru/3.2/library/collections.html#collections.MappingView) | [`Sized`](https://python-all.ru/3.2/library/collections.html#collections.Sized) |  | `__len__` |791| [`ItemsView`](https://python-all.ru/3.2/library/collections.html#collections.ItemsView) | [`MappingView`](https://python-all.ru/3.2/library/collections.html#collections.MappingView), [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) |  | `__contains__`, `__iter__` |792| [`KeysView`](https://python-all.ru/3.2/library/collections.html#collections.KeysView) | [`MappingView`](https://python-all.ru/3.2/library/collections.html#collections.MappingView), [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) |  | `__contains__`, `__iter__` |793| [`ValuesView`](https://python-all.ru/3.2/library/collections.html#collections.ValuesView) | [`MappingView`](https://python-all.ru/3.2/library/collections.html#collections.MappingView) |  | `__contains__`, `__iter__` |794795#### `class collections.Container`796797#### `class collections.Hashable`798799#### `class collections.Sized`800801#### `class collections.Callable`802803Абстрактные базовые классы (ABC) для классов, предоставляющих соответственно методы [`__contains__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__contains__), [`__hash__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__hash__), [`__len__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__len__) и [`__call__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__call__).804805#### `class collections.Iterable`806807ABC для классов, предоставляющих метод [`__iter__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__iter__). См. также определение [*итерируемого объекта*](https://python-all.ru/3.2/glossary.html#term-iterable).808809#### `class collections.Iterator`810811ABC for classes that provide the [`__iter__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__iter__) and `__next__()` methods. See also the definition of [*iterator*](https://python-all.ru/3.2/glossary.html#term-iterator).812813#### `class collections.Sequence`814815#### `class collections.MutableSequence`816817ABC для неизменяемых и изменяемых [*последовательностей*](https://python-all.ru/3.2/glossary.html#term-sequence).818819#### `class collections.Set`820821#### `class collections.MutableSet`822823ABC для наборов только для чтения и изменяемых наборов.824825#### `class collections.Mapping`826827#### `class collections.MutableMapping`828829ABC для неизменяемых и изменяемых [*отображений*](https://python-all.ru/3.2/glossary.html#term-mapping).830831#### `class collections.MappingView`832833#### `class collections.ItemsView`834835#### `class collections.KeysView`836837#### `class collections.ValuesView`838839ABC для [*представлений*](https://python-all.ru/3.2/glossary.html#term-view) отображений, элементов, ключей и значений.840841Эти ABC позволяют проверять, предоставляют ли классы или их экземпляры определённую функциональность, например:842843```python844size = None845if isinstance(myvar, collections.Sized):846    size = len(myvar)847```848849Некоторые ABC также полезны в качестве примесей, упрощающих разработку классов, поддерживающих API контейнеров. Например, чтобы написать класс, поддерживающий полный API [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set), достаточно предоставить три базовых абстрактных метода: [`__contains__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__contains__), [`__iter__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__iter__) и [`__len__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__len__). ABC предоставляет остальные методы, такие как [`__and__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__and__) и `isdisjoint()`850851```python852class ListBasedSet(collections.Set):853     ''' Альтернативная реализация множества, ориентированная на экономию памяти, а не на скорость854         и не требующая, чтобы элементы множества были хэшируемыми. '''855     def __init__(self, iterable):856         self.elements = lst = []857         for value in iterable:858             if value not in lst:859                 lst.append(value)860     def __iter__(self):861         return iter(self.elements)862     def __contains__(self, value):863         return value in self.elements864     def __len__(self):865         return len(self.elements)866867s1 = ListBasedSet('abcdef')868s2 = ListBasedSet('defghi')869overlap = s1 & s2            # Метод __and__() поддерживается автоматически870```871872Замечания по использованию [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) и [`MutableSet`](https://python-all.ru/3.2/library/collections.html#collections.MutableSet) в качестве миксина:8738741. Поскольку некоторые операции над множествами создают новые множества, методам миксина по умолчанию требуется способ создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида `ClassName(iterable)`. Это предположение вынесено во внутренний метод класса `_from_iterable()`, который вызывает `cls(iterable)` для создания нового множества. Если миксин [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) используется в классе с другой сигнатурой конструктора, потребуется переопределить `_from_iterable()` методом класса, который сможет создавать новые экземпляры из итерируемого аргумента.8752. Чтобы переопределить операции сравнения (предположительно для скорости, так как семантика фиксирована), переопределите [`__le__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__le__), и остальные операции автоматически последуют этому примеру.8763. Примесь [`Set`](https://python-all.ru/3.2/library/collections.html#collections.Set) предоставляет метод `_hash()` для вычисления хеш-значения множества; однако [`__hash__()`](https://python-all.ru/3.2/reference/datamodel.html#object.__hash__) не определён, поскольку не все множества являются хешируемыми или неизменяемыми. Чтобы добавить хешируемость множеству с помощью примесей, унаследуйтесь от [`Set()`](https://python-all.ru/3.2/library/collections.html#collections.Set) и [`Hashable()`](https://python-all.ru/3.2/library/collections.html#collections.Hashable), затем определите `__hash__ = Set._hash`.877878> **См. также**879>880> - [Рецепт OrderedSet](https://python-all.ru/3.2/library/collections.html) для примера, построенного на основе [`MutableSet`](https://python-all.ru/3.2/library/collections.html#collections.MutableSet).881> - Для получения дополнительной информации об ABC см. модуль [`abc`](https://python-all.ru/3.2/library/abc.html#module-abc) и [**PEP 3119**](https://python-all.ru/3.2/library/collections.html).882