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

collections.md

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

1> **Источник:** https://python-all.ru/2.7/library/collections.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 8.3. [`collections`](https://python-all.ru/2.7/library/collections.html#module-collections) – Высокопроизводительные контейнерные типы данных89Новое в версии 2.4.1011**Исходный код:** [Lib/collections.py](https://python-all.ru/src/2.7/Lib/collections.py) и [Lib/\_abcoll.py](https://python-all.ru/src/2.7/Lib/_abcoll.py)1213---1415Этот модуль предоставляет специализированные типы данных-контейнеры в качестве альтернативы встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict), `list`, [`set`](https://python-all.ru/2.7/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/2.7/library/functions.html#tuple).1617| [`namedtuple()`](https://python-all.ru/2.7/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями | Новое в версии 2.6. |18| --- | --- | --- |19| [`deque`](https://python-all.ru/2.7/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов | Новое в версии 2.4. |20| [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов | Новое в версии 2.7. |21| [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей | Новое в версии 2.7. |22| [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений | Новое в версии 2.5. |2324В дополнение к конкретным классам-контейнерам, модуль collections предоставляет [абстрактные базовые классы](https://python-all.ru/2.7/library/collections.html#collections-abstract-base-classes), которые можно использовать для проверки того, предоставляет ли класс определённый интерфейс, например, является ли он хешируемым или отображением.2526## 8.3.1. [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) объекты2728Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:2930```python31>>> # Подсчитать вхождения слов в списке32>>> cnt = Counter()33>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:34...     cnt[word] += 135>>> cnt36Counter({'blue': 3, 'red': 2, 'green': 1})3738>>> # Найти десять самых распространённых слов в «Гамлете»39>>> import re40>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())41>>> Counter(words).most_common(10)42[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),43 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]44```4546#### `class collections.Counter([iterable-or-mapping])`4748Класс [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) является подклассом [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict) для подсчёта хешируемых объектов. Это неупорядоченная коллекция, в которой элементы хранятся в качестве ключей словаря, а их количество – в качестве значений словаря. Количество может быть любым целым числом, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) похож на мешки или мультимножества в других языках.4950Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):5152```python53>>> c = Counter()                           # новый пустой счётчик54>>> c = Counter('gallahad')                 # новый счётчик из итерируемого объекта55>>> c = Counter({'red': 4, 'blue': 2})      # новый счётчик из отображения56>>> c = Counter(cats=4, dogs=8)             # новый счётчик из именованных аргументов57```5859Объекты Counter имеют интерфейс словаря, за исключением того, что они возвращают ноль для отсутствующих элементов вместо возбуждения [`KeyError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyError):6061```python62>>> c = Counter(['eggs', 'ham'])63>>> c['bacon']                              # счёт отсутствующего элемента равен нулю64065```6667Установка количества в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:6869```python70>>> c['sausage'] = 0                        # запись счётчика с нулевым значением71>>> del c['sausage']                        # del действительно удаляет запись72```7374Новое в версии 2.7.7576Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:7778#### `elements()`7980Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его счётчике. Элементы возвращаются в произвольном порядке. Если счётчик элемента меньше единицы, [`elements()`](https://python-all.ru/2.7/library/collections.html#collections.Counter.elements) игнорирует его.8182```python83>>> c = Counter(a=4, b=2, c=0, d=-2)84>>> list(c.elements())85['a', 'a', 'a', 'a', 'b', 'b']86```8788#### `most_common([n])`8990Возвращает список из *n* наиболее часто встречающихся элементов и их количества, от наиболее частых к наименее частым. Если *n* опущено или `None`, [`most_common()`](https://python-all.ru/2.7/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковыми количествами упорядочиваются произвольно:9192```python93>>> Counter('abracadabra').most_common(3)94[('a', 5), ('r', 2), ('b', 2)]95```9697#### `subtract([iterable-or-mapping])`9899Элементы вычитаются из *итерируемого объекта* или из другого *отображения* (или счётчика). Подобно [`dict.update()`](https://python-all.ru/2.7/library/stdtypes.html#dict.update), но вычитает количества вместо замены. Как входные, так и выходные значения могут быть нулевыми или отрицательными.100101```python102>>> c = Counter(a=4, b=2, c=0, d=-2)103>>> d = Counter(a=1, b=2, c=3, d=4)104>>> c.subtract(d)105>>> c106Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})107```108109Обычные методы словарей доступны для объектов [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter), за исключением двух, которые работают с счётчиками иначе.110111#### `fromkeys(iterable)`112113Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter).114115#### `update([iterable-or-mapping])`116117Элементы подсчитываются из *итерируемого объекта* или добавляются из другого *отображения* (или счётчика). Как и [`dict.update()`](https://python-all.ru/2.7/library/stdtypes.html#dict.update), но увеличивает счётчики вместо их замены. Кроме того, *итерируемый объект* должен быть последовательностью элементов, а не последовательностью `(key, value)` пар.118119Типичные приёмы работы с объектами [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter):120121```python122sum(c.values())                 # сумма всех значений123c.clear()                       # сбросить все значения124list(c)                         # список уникальных элементов125set(c)                          # преобразовать в множество126dict(c)                         # преобразовать в обычный словарь127c.items()                       # преобразовать в список пар (elem, cnt)128Counter(dict(list_of_pairs))    # создать из списка пар (элемент, кол-во)129c.most_common()[:-n-1:-1]       # n наименее частых элементов130c += Counter()                  # удалить нулевые и отрицательные значения131```132133Для объединения объектов [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) в мультимножества (счётчики с положительными количествами) предоставляется несколько математических операций. Сложение и вычитание комбинируют счётчики, складывая или вычитая количества соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих количеств. Каждая операция может принимать входные данные со знаковыми количествами, но в результате будут исключены значения с нулевыми или отрицательными количествами.134135```python136>>> c = Counter(a=3, b=1)137>>> d = Counter(a=1, b=2)138>>> c + d                       # сложение двух счётчиков: c[x] + d[x]139Counter({'a': 4, 'b': 3})140>>> c - d                       # вычитание (остаются только положительные значения)141Counter({'a': 2})142>>> c & d                       # пересечение: min(c[x], d[x])143Counter({'a': 1, 'b': 1})144>>> c | d                       # объединение: max(c[x], d[x])145Counter({'a': 3, 'b': 2})146```147148> **Примечание**149>150> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.151>152> - Сам класс [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения должны быть числами, представляющими счётчики, но в поле значения *можно* хранить что угодно.153> - Метод `most_common()` требует только упорядочиваемости значений.154> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа будут работать, и отрицательные значения поддерживаются. То же самое верно для `update()` и `subtract()`, которые допускают отрицательные и нулевые значения как для входных, так и для выходных данных.155> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.156> - Метод `elements()` требует целочисленных счётчиков. Он игнорирует нулевые и отрицательные счётчики.157158> **См. также**159>160> - [Класс Counter](https://python-all.ru/2.7/library/collections.html) адаптирован для Python 2.5 и раннего [рецепта Bag](https://python-all.ru/2.7/library/collections.html) для Python 2.4.161> - [Класс Bag](https://python-all.ru/2.7/library/collections.html) в Smalltalk.162> - Статья в Википедии о [мультимножествах](https://python-all.ru/2.7/library/collections.html).163> - [Мультимножества в C++](https://python-all.ru/2.7/library/collections.html): учебное пособие с примерами.164> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.165> - Чтобы перечислить все различные мультимножества заданного размера из заданного набора элементов, обратитесь к [`itertools.combinations_with_replacement()`](https://python-all.ru/2.7/library/itertools.html#itertools.combinations_with_replacement).166>167>   > map(Counter, combinations\_with\_replacement(‘ABC’, 2)) –\> AA AB AC BB BC CC168169## 8.3.2. [`deque`](https://python-all.ru/2.7/library/collections.html#collections.deque) объекты170171#### `class collections.deque([iterable[, maxlen]])`172173Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/2.7/library/collections.html#collections.deque.append)) данными из *итерируемого объекта*. Если *итерируемый объект* не указан, новый deque пуст.174175Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.176177Хотя объекты `list` поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и влекут за собой затраты на перемещение памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.178179Новое в версии 2.4.180181Если *maxlen* не указан или равен `None`, deques могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque ограниченной длины заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.182183Изменено в версии 2.6: Добавлен параметр *maxlen*.184185Объекты deque поддерживают следующие методы:186187#### `append(x)`188189Добавляет *x* в правую часть deque.190191#### `appendleft(x)`192193Добавляет *x* в левую часть deque.194195#### `clear()`196197Удаляет все элементы из deque, после чего его длина равна 0.198199#### `count(x)`200201Подсчитывает количество элементов deque, равных *x*.202203Новое в версии 2.7.204205#### `extend(iterable)`206207Расширяет правую часть deque, добавляя элементы из итерируемого объекта.208209#### `extendleft(iterable)`210211Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.212213#### `pop()`214215Удаляет и возвращает элемент из правой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IndexError).216217#### `popleft()`218219Удаляет и возвращает элемент из левой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IndexError).220221#### `remove(value)`222223Удаляет первое вхождение *значения*. Если не найдено, вызывает исключение [`ValueError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ValueError).224225Новое в версии 2.5.226227#### `reverse()`228229Переворачивает элементы deque на месте и возвращает `None`.230231Новое в версии 2.7.232233#### `rotate(n=1)`234235Поворачивает deque на *n* шагов вправо. Если *n* отрицательно, выполняет поворот влево.236237Когда deque не пуст, поворот на один шаг вправо эквивалентен `d.appendleft(d.pop())`, а поворот на один шаг влево – `d.append(d.popleft())`.238239Объекты deque также предоставляют один атрибут только для чтения:240241#### `maxlen`242243Максимальный размер дека или `None`, если неограничен.244245Новое в версии 2.7.246247В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/2.7/reference/expressions.html#in) и обращения по индексу, такие как `d[-1]`. Доступ по индексу выполняется за O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.248249Пример:250251```pycon252>>> from collections import deque253>>> d = deque('ghi')                 # создать новый deque с тремя элементами254>>> for elem in d:                   # обход элементов deque255...     print elem.upper()256G257H258I259260>>> d.append('j')                    # добавить новый элемент справа261>>> d.appendleft('f')                # добавить новый элемент слева262>>> d                                # показать представление deque263deque(['f', 'g', 'h', 'i', 'j'])264265>>> d.pop()                          # вернуть и удалить правый элемент266'j'267>>> d.popleft()                      # вернуть и удалить левый элемент268'f'269>>> list(d)                          # вывести содержимое deque270['g', 'h', 'i']271>>> d[0]                             # посмотреть левый элемент272'g'273>>> d[-1]                            # посмотреть правый элемент274'i'275276>>> list(reversed(d))                # вывести содержимое deque в обратном порядке277['i', 'h', 'g']278>>> 'h' in d                         # поиск в deque279True280>>> d.extend('jkl')                  # добавить несколько элементов за раз281>>> d282deque(['g', 'h', 'i', 'j', 'k', 'l'])283>>> d.rotate(1)                      # поворот вправо284>>> d285deque(['l', 'g', 'h', 'i', 'j', 'k'])286>>> d.rotate(-1)                     # поворот влево287>>> d288deque(['g', 'h', 'i', 'j', 'k', 'l'])289290>>> deque(reversed(d))               # создать новую deque в обратном порядке291deque(['l', 'k', 'j', 'i', 'h', 'g'])292>>> d.clear()                        # очистить deque293>>> d.pop()                          # невозможно извлечь элемент из пустой deque294Traceback (most recent call last):295  File "<pyshell#6>", line 1, in -toplevel-296    d.pop()297IndexError: pop from an empty deque298299>>> d.extendleft('abc')              # extendleft() меняет порядок ввода на обратный300>>> d301deque(['c', 'b', 'a'])302```303304### 8.3.2.1. [`deque`](https://python-all.ru/2.7/library/collections.html#collections.deque) Рецепты305306В этом разделе рассматриваются различные подходы к работе с деками.307308Деки с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:309310```python311def tail(filename, n=10):312    'Return the last n lines of a file'313    return deque(open(filename), n)314```315316Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:317318```python319def moving_average(iterable, n=3):320    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0321    # http://en.wikipedia.org/wiki/Moving_average322    it = iter(iterable)323    d = deque(itertools.islice(it, n-1))324    d.appendleft(0)325    s = sum(d)326    for elem in it:327        s += elem - d.popleft()328        d.append(elem)329        yield s / float(n)330```331332Метод `rotate()` позволяет реализовать [`deque`](https://python-all.ru/2.7/library/collections.html#collections.deque) срезы и удаление. Например, чистая реализация `del d[n]` на Python использует метод `rotate()` для позиционирования элементов, которые нужно извлечь:333334```python335def delete_nth(d, n):336    d.rotate(-n)337    d.popleft()338    d.rotate(n)339```340341To implement [`deque`](https://python-all.ru/2.7/library/collections.html#collections.deque) slicing, use a similar approach applying `rotate()` to bring a target element to the left side of the deque. Remove old entries with `popleft()`, add new entries with `extend()`, and then reverse the rotation. With minor variations on that approach, it is easy to implement Forth style stack manipulations such as `dup`, `drop`, `swap`, `over`, `pick`, `rot`, and `roll`.342343## 8.3.3. [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) объекты344345#### `class collections.defaultdict([default_factory[, ...]])`346347Возвращает новый объект, похожий на словарь. [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict), и здесь не описывается.348349Первый аргумент задает начальное значение для атрибута [`default_factory`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.default_factory); по умолчанию он равен `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict), включая именованные аргументы.350351Новое в версии 2.5.352353[`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) объекты поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict):354355#### `__missing__(key)`356357Если атрибут [`default_factory`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.default_factory) равен `None`, возникает исключение [`KeyError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyError) с аргументом *key*.358359Если [`default_factory`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов для предоставления значения по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.360361Если вызов [`default_factory`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.default_factory) вызывает исключение, это исключение распространяется без изменений.362363Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict), когда запрошенный ключ не найден; все, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__getitem__).364365Обратите внимание, что [`__missing__()`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.__missing__) *не* вызывается ни для каких операций, кроме [`__getitem__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__getitem__). Это означает, что `get()` будет, как обычные словари, возвращать `None` по умолчанию, а не использовать [`default_factory`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.default_factory).366367[`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) объекты поддерживают следующую переменную экземпляра:368369#### `default_factory`370371Этот атрибут используется методом [`__missing__()`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он передан, или `None`, если не передан.372373### 8.3.3.1. [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) Примеры374375Используя `list` в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:376377```python378>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]379>>> d = defaultdict(list)380>>> for k, v in s:381...     d[k].append(v)382...383>>> d.items()384[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]385```386387Когда ключ встречается впервые, его еще нет в отображении; поэтому запись автоматически создается с помощью функции `default_factory`, которая возвращает пустой `list`. Затем операция `list.append()` присоединяет значение к новому списку. Когда ключи встречаются снова, поиск выполняется обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет еще одно значение в список. Этот метод проще и быстрее, чем эквивалентный метод с использованием [`dict.setdefault()`](https://python-all.ru/2.7/library/stdtypes.html#dict.setdefault):388389```python390>>> d = {}391>>> for k, v in s:392...     d.setdefault(k, []).append(v)393...394>>> d.items()395[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]396```397398Установка `default_factory` в [`int`](https://python-all.ru/2.7/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) удобным для подсчёта (как bag или мультимножество в других языках):399400```python401>>> s = 'mississippi'402>>> d = defaultdict(int)403>>> for k in s:404...     d[k] += 1405...406>>> d.items()407[('i', 4), ('p', 2), ('s', 4), ('m', 1)]408```409410Когда буква встречается впервые, в отображении она отсутствует, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/2.7/library/functions.html#int) для получения нулевого значения по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.411412Функция [`int()`](https://python-all.ru/2.7/library/functions.html#int), которая всегда возвращает ноль, является лишь частным случаем константных функций. Более быстрый и гибкий способ создания константных функций – использование [`itertools.repeat()`](https://python-all.ru/2.7/library/itertools.html#itertools.repeat), который может предоставлять любое константное значение (не только ноль):413414```python415>>> def constant_factory(value):416...     return itertools.repeat(value).next417>>> d = defaultdict(constant_factory('<missing>'))418>>> d.update(name='John', action='ran')419>>> '%(name)s %(action)s to %(object)s' % d420'John ran to <missing>'421```422423Установка `default_factory` в [`set`](https://python-all.ru/2.7/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/2.7/library/collections.html#collections.defaultdict) удобным для построения словаря множеств:424425```python426>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]427>>> d = defaultdict(set)428>>> for k, v in s:429...     d[k].add(v)430...431>>> d.items()432[('blue', set([2, 4])), ('red', set([1, 3]))]433```434435## 8.3.4. [`namedtuple()`](https://python-all.ru/2.7/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями436437Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.438439#### `collections.namedtuple(typename, field_names[, verbose=False][, rename=False])`440441Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежам, поля которых доступны через атрибуты, а также поддерживают индексацию и итерацию. Экземпляры подкласса также имеют полезную docstring (с именем типа и именами полей) и полезный метод [`__repr__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.442443Параметр *field\_names* представляет собой последовательность строк, например `['x', 'y']`. В качестве альтернативы *field\_names* может быть единой строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`.444445Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, and underscores but do not start with a digit or underscore and cannot be a [`keyword`](https://python-all.ru/2.7/library/keyword.html#module-keyword) such as *class*, *for*, *return*, *global*, *pass*, *print*, or *raise*.446447Если *rename* равен true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, устраняя ключевое слово `def` и дублирующееся имя поля `abc`.448449Если *verbose* равно true, определение класса выводится непосредственно перед его созданием.450451Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.452453Новое в версии 2.6.454455Изменено в версии 2.7: добавлена поддержка *rename*.456457Пример:458459```pycon460>>> Point = namedtuple('Point', ['x', 'y'], verbose=True)461class Point(tuple):462    'Point(x, y)'463464    __slots__ = ()465466    _fields = ('x', 'y')467468    def __new__(_cls, x, y):469        'Create new instance of Point(x, y)'470        return _tuple.__new__(_cls, (x, y))471472    @classmethod473    def _make(cls, iterable, new=tuple.__new__, len=len):474        'Make a new Point object from a sequence or iterable'475        result = new(cls, iterable)476        if len(result) != 2:477            raise TypeError('Expected 2 arguments, got %d' % len(result))478        return result479480    def __repr__(self):481        'Return a nicely formatted representation string'482        return 'Point(x=%r, y=%r)' % self483484    def _asdict(self):485        'Return a new OrderedDict which maps field names to their values'486        return OrderedDict(zip(self._fields, self))487488    def _replace(_self, **kwds):489        'Return a new Point object replacing specified fields with new values'490        result = _self._make(map(kwds.pop, ('x', 'y'), _self))491        if kwds:492            raise ValueError('Got unexpected field names: %r' % kwds.keys())493        return result494495    def __getnewargs__(self):496        'Return self as a plain tuple.  Used by copy and pickle.'497        return tuple(self)498499    __dict__ = _property(_asdict)500501    def __getstate__(self):502        'Exclude the OrderedDict from pickling'503        pass504505    x = _property(_itemgetter(0), doc='Alias for field number 0')506507    y = _property(_itemgetter(1), doc='Alias for field number 1')508509>>> p = Point(11, y=22)     # создать экземпляр с позиционными или именованными аргументами510>>> p[0] + p[1]             # доступен по индексу, как обычный кортеж (11, 22)51133512>>> x, y = p                # распаковывается как обычный кортеж513>>> x, y514(11, 22)515>>> p.x + p.y               # поля также доступны по имени51633517>>> p                       # читаемое __repr__ в стиле name=value518Point(x=11, y=22)519```520521Именованные кортежи особенно полезны для присваивания имён полей кортежам результатов, возвращаемых модулями [`csv`](https://python-all.ru/2.7/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/2.7/library/sqlite3.html#module-sqlite3):522523```python524EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')525526import csv527for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):528    print emp.name, emp.title529530import sqlite3531conn = sqlite3.connect('/companydata')532cursor = conn.cursor()533cursor.execute('SELECT name, age, title, department, paygrade FROM employees')534for emp in map(EmployeeRecord._make, cursor.fetchall()):535    print emp.name, emp.title536```537538В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и один атрибут. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.539540#### `classmethod somenamedtuple._make(iterable)`541542Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.543544```pycon545>>> t = [11, 22]546>>> Point._make(t)547Point(x=11, y=22)548```549550#### `somenamedtuple._asdict()`551552Возвращает новый [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict), который отображает имена полей в соответствующие значения:553554```python555>>> p = Point(x=11, y=22)556>>> p._asdict()557OrderedDict([('x', 11), ('y', 22)])558```559560Изменено в версии 2.7: Возвращает [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict).561562#### `somenamedtuple._replace(**kwargs)`563564Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:565566```python567>>> p = Point(x=11, y=22)568>>> p._replace(x=33)569Point(x=33, y=22)570571>>> for partnum, record in inventory.items():572...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())573```574575#### `somenamedtuple._fields`576577Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.578579```pycon580>>> p._fields            # просмотреть имена полей581('x', 'y')582583>>> Color = namedtuple('Color', 'red green blue')584>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)585>>> Pixel(11, 22, 128, 255, 0)586Pixel(x=11, y=22, red=128, green=255, blue=0)587```588589Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/2.7/library/functions.html#getattr) :590591```python592>>> getattr(p, 'x')59311594```595596Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [Распаковка списков аргументов](https://python-all.ru/2.7/tutorial/controlflow.html#tut-unpacking-arguments)):597598```python599>>> d = {'x': 11, 'y': 22}600>>> Point(**d)601Point(x=11, y=22)602```603604Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:605606```python607>>> class Point(namedtuple('Point', 'x y')):608...     __slots__ = ()609...     @property610...     def hypot(self):611...         return (self.x ** 2 + self.y ** 2) ** 0.5612...     def __str__(self):613...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)614...615>>> for p in Point(3, 4), Point(14, 5/7.):616...     print p617Point: x= 3.000  y= 4.000  hypot= 5.000618Point: x=14.000  y= 0.714  hypot=14.018619```620621Подкласс, показанный выше, устанавливает `__slots__` в пустой кортеж. Это помогает снизить требования к памяти, предотвращая создание словарей экземпляров.622623Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа из атрибута `_fields`:624625```python626>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))627```628629Значения по умолчанию могут быть реализованы с помощью `_replace()` для настройки экземпляра-прототипа:630631```python632>>> Account = namedtuple('Account', 'owner balance transaction_count')633>>> default_account = Account('<owner name>', 0.0, 0)634>>> johns_account = default_account._replace(owner='John')635```636637Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простое объявление класса:638639```python640>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))641>>> Status.open, Status.pending, Status.closed642(0, 1, 2)643>>> class Status:644...     open, pending, closed = range(3)645```646647> **См. также**648>649> [Рецепт именованного кортежа](https://python-all.ru/2.7/library/collections.html) адаптирован для Python 2.4.650651## 8.3.5. [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) объекты652653Упорядоченные словари работают как обычные словари, но запоминают порядок, в котором были добавлены элементы. При итерации по упорядоченному словарю элементы возвращаются в том порядке, в котором их ключи были впервые добавлены.654655#### `class collections.OrderedDict([items])`656657Возвращает экземпляр подкласса dict, поддерживающего обычные методы [`dict`](https://python-all.ru/2.7/library/stdtypes.html#dict). *OrderedDict* – это словарь, который запоминает порядок, в котором ключи были впервые вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки не изменяется. Удаление записи и повторная вставка переместит её в конец.658659Новое в версии 2.7.660661#### `OrderedDict.popitem(last=True)`662663Метод [`popitem()`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (ключ, значение). Пары возвращаются в порядке LIFO, если *last* равно true, или в порядке FIFO, если false.664665Помимо обычных методов отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/2.7/library/functions.html#reversed).666667Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) чувствительны к порядку и реализованы как `list(od1.items())==list(od2.items())`. Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/2.7/library/collections.html#collections.Mapping) нечувствительны к порядку, как обычные словари. Это позволяет подставлять объекты [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) в любом месте, где используется обычный словарь.668669Конструктор [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) и метод `update()` принимают именованные аргументы, но их порядок теряется, поскольку семантика вызова функций Python передаёт именованные аргументы через обычный неупорядоченный словарь.670671> **См. также**672>673> [Эквивалентный рецепт OrderedDict](https://python-all.ru/2.7/library/collections.html) , работающий на Python 2.4 или новее.674675### 8.3.5.1. [`OrderedDict`](https://python-all.ru/2.7/library/collections.html#collections.OrderedDict) Примеры и рецепты676677Поскольку упорядоченный словарь запоминает порядок вставки, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:678679```python680>>> # обычный неотсортированный словарь681>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}682683>>> # словарь, отсортированный по ключу684>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))685OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])686687>>> # словарь, отсортированный по значению688>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))689OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])690691>>> # словарь, отсортированный по длине строки ключа692>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))693OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])694```695696Новые отсортированные словари сохраняют порядок сортировки при удалении записей. Но при добавлении новых ключей они добавляются в конец, и сортировка не сохраняется.697698Также несложно создать вариант упорядоченного словаря, который запоминает порядок, в котором ключи были *в последний раз* вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки меняется и перемещается в конец:699700```python701class LastUpdatedOrderedDict(OrderedDict):702    'Store items in the order the keys were last added'703704    def __setitem__(self, key, value):705        if key in self:706            del self[key]707        OrderedDict.__setitem__(self, key, value)708```709710Упорядоченный словарь можно комбинировать с классом [`Counter`](https://python-all.ru/2.7/library/collections.html#collections.Counter), чтобы счётчик запоминал порядок, в котором элементы встречаются впервые:711712```python713class OrderedCounter(Counter, OrderedDict):714     'Counter that remembers the order elements are first encountered'715716     def __repr__(self):717         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))718719     def __reduce__(self):720         return self.__class__, (OrderedDict(self),)721```722723## 8.3.6. Абстрактные базовые классы коллекций724725Модуль collections предоставляет следующие [абстрактные базовые классы](https://python-all.ru/2.7/glossary.html#term-abstract-base-class):726727| ABC | Наследует от | Абстрактные методы | Методы-примеси |728| --- | --- | --- | --- |729| [`Container`](https://python-all.ru/2.7/library/collections.html#collections.Container) |  | `__contains__` |  |730| [`Hashable`](https://python-all.ru/2.7/library/collections.html#collections.Hashable) |  | `__hash__` |  |731| [`Iterable`](https://python-all.ru/2.7/library/collections.html#collections.Iterable) |  | `__iter__` |  |732| [`Iterator`](https://python-all.ru/2.7/library/collections.html#collections.Iterator) | [`Iterable`](https://python-all.ru/2.7/library/collections.html#collections.Iterable) | `next` | `__iter__` |733| [`Sized`](https://python-all.ru/2.7/library/collections.html#collections.Sized) |  | `__len__` |  |734| [`Callable`](https://python-all.ru/2.7/library/collections.html#collections.Callable) |  | `__call__` |  |735| [`Sequence`](https://python-all.ru/2.7/library/collections.html#collections.Sequence) | [`Sized`](https://python-all.ru/2.7/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/2.7/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/2.7/library/collections.html#collections.Container) | `__getitem__`, `__len__` | `__contains__`, `__iter__`, `__reversed__`, `index` и `count` |736| [`MutableSequence`](https://python-all.ru/2.7/library/collections.html#collections.MutableSequence) | [`Sequence`](https://python-all.ru/2.7/library/collections.html#collections.Sequence) | `__getitem__`, `__setitem__`, `__delitem__`, `__len__`, `insert` | Наследуемые методы [`Sequence`](https://python-all.ru/2.7/library/collections.html#collections.Sequence) и `append`, `reverse`, `extend`, `pop`, `remove` и `__iadd__` |737| [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) | [`Sized`](https://python-all.ru/2.7/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/2.7/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/2.7/library/collections.html#collections.Container) | `__contains__`, `__iter__`, `__len__` | `__le__`, `__lt__`, `__eq__`, `__ne__`, `__gt__`, `__ge__`, `__and__`, `__or__`, `__sub__`, `__xor__` и `isdisjoint` |738| [`MutableSet`](https://python-all.ru/2.7/library/collections.html#collections.MutableSet) | [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) | `__contains__`, `__iter__`, `__len__`, `add`, `discard` | Унаследованные методы [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) и `clear`, `pop`, `remove`, `__ior__`, `__iand__`, `__ixor__` и `__isub__` |739| [`Mapping`](https://python-all.ru/2.7/library/collections.html#collections.Mapping) | [`Sized`](https://python-all.ru/2.7/library/collections.html#collections.Sized), [`Iterable`](https://python-all.ru/2.7/library/collections.html#collections.Iterable), [`Container`](https://python-all.ru/2.7/library/collections.html#collections.Container) | `__getitem__`, `__iter__`, `__len__` | `__contains__`, `keys`, `items`, `values`, `get`, `__eq__` и `__ne__` |740| [`MutableMapping`](https://python-all.ru/2.7/library/collections.html#collections.MutableMapping) | [`Mapping`](https://python-all.ru/2.7/library/collections.html#collections.Mapping) | `__getitem__`, `__setitem__`, `__delitem__`, `__iter__`, `__len__` | Унаследованные методы [`Mapping`](https://python-all.ru/2.7/library/collections.html#collections.Mapping) и `pop`, `popitem`, `clear`, `update`, и `setdefault` |741| [`MappingView`](https://python-all.ru/2.7/library/collections.html#collections.MappingView) | [`Sized`](https://python-all.ru/2.7/library/collections.html#collections.Sized) |  | `__len__` |742| [`ItemsView`](https://python-all.ru/2.7/library/collections.html#collections.ItemsView) | [`MappingView`](https://python-all.ru/2.7/library/collections.html#collections.MappingView), [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) |  | `__contains__`, `__iter__` |743| [`KeysView`](https://python-all.ru/2.7/library/collections.html#collections.KeysView) | [`MappingView`](https://python-all.ru/2.7/library/collections.html#collections.MappingView), [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) |  | `__contains__`, `__iter__` |744| [`ValuesView`](https://python-all.ru/2.7/library/collections.html#collections.ValuesView) | [`MappingView`](https://python-all.ru/2.7/library/collections.html#collections.MappingView) |  | `__contains__`, `__iter__` |745746#### `class collections.Container`747748#### `class collections.Hashable`749750#### `class collections.Sized`751752#### `class collections.Callable`753754ABC для классов, которые предоставляют соответственно методы [`__contains__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__contains__), [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__), [`__len__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__len__) и [`__call__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__call__).755756#### `class collections.Iterable`757758ABC для классов, которые предоставляют метод [`__iter__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__iter__). См. также определение [итерируемого объекта](https://python-all.ru/2.7/glossary.html#term-iterable).759760#### `class collections.Iterator`761762ABC для классов, которые предоставляют методы [`__iter__()`](https://python-all.ru/2.7/library/stdtypes.html#iterator.__iter__) и [`next()`](https://python-all.ru/2.7/library/stdtypes.html#iterator.next). См. также определение [iterator](https://python-all.ru/2.7/glossary.html#term-iterator).763764#### `class collections.Sequence`765766#### `class collections.MutableSequence`767768ABC для неизменяемых и изменяемых [последовательностей](https://python-all.ru/2.7/glossary.html#term-sequence).769770#### `class collections.Set`771772#### `class collections.MutableSet`773774ABC для наборов только для чтения и изменяемых наборов.775776#### `class collections.Mapping`777778#### `class collections.MutableMapping`779780ABC для неизменяемых и изменяемых [отображений](https://python-all.ru/2.7/glossary.html#term-mapping).781782#### `class collections.MappingView`783784#### `class collections.ItemsView`785786#### `class collections.KeysView`787788#### `class collections.ValuesView`789790ABC для [представлений](https://python-all.ru/2.7/glossary.html#term-dictionary-view) отображений, элементов, ключей и значений.791792Эти ABC позволяют проверять, предоставляют ли классы или их экземпляры определённую функциональность, например:793794```python795size = None796if isinstance(myvar, collections.Sized):797    size = len(myvar)798```799800Некоторые из ABC также полезны в качестве примесей, упрощающих разработку классов, поддерживающих контейнерные API. Например, чтобы написать класс, поддерживающий полный API [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set), достаточно предоставить три базовых абстрактных метода: [`__contains__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__contains__), [`__iter__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__iter__) и [`__len__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__len__). ABC предоставляет остальные методы, такие как [`__and__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__and__) и `isdisjoint()`.801802```python803class ListBasedSet(collections.Set):804     ''' Альтернативная реализация множества, ориентированная на экономию памяти, а не на скорость805         и не требующая, чтобы элементы множества были хэшируемыми. '''806     def __init__(self, iterable):807         self.elements = lst = []808         for value in iterable:809             if value not in lst:810                 lst.append(value)811812     def __iter__(self):813         return iter(self.elements)814815     def __contains__(self, value):816         return value in self.elements817818     def __len__(self):819         return len(self.elements)820821s1 = ListBasedSet('abcdef')822s2 = ListBasedSet('defghi')823overlap = s1 & s2            # Метод __and__() поддерживается автоматически824```825826Замечания по использованию [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) и [`MutableSet`](https://python-all.ru/2.7/library/collections.html#collections.MutableSet) в качестве примеси:8278281. Поскольку некоторые операции над множествами создают новые множества, методам примесей по умолчанию нужен способ создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида `ClassName(iterable)`. Это допущение вынесено во внутренний метод класса `_from_iterable()`, который вызывает `cls(iterable)` для создания нового множества. Если примесь [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) используется в классе с другой сигнатурой конструктора, потребуется переопределить `_from_iterable()` методом класса, который умеет создавать новые экземпляры из итерируемого аргумента.8292. Чтобы переопределить сравнения (предположительно для скорости, так как семантика фиксирована), переопределите [`__le__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__le__) и [`__ge__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__ge__), тогда остальные операции будут автоматически им следовать.8303. Миксин [`Set`](https://python-all.ru/2.7/library/collections.html#collections.Set) предоставляет метод `_hash()` для вычисления хеша множества; однако [`__hash__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__hash__) не определён, так как не все множества хешируемы или неизменяемы. Чтобы добавить хешируемость множества с помощью миксинов, унаследуйте от обоих [`Set()`](https://python-all.ru/2.7/library/collections.html#collections.Set) и [`Hashable()`](https://python-all.ru/2.7/library/collections.html#collections.Hashable), а затем определите `__hash__ = Set._hash`.831832> **См. также**833>834> - [Рецепт OrderedSet](https://python-all.ru/2.7/library/collections.html) для примера, построенного на [`MutableSet`](https://python-all.ru/2.7/library/collections.html#collections.MutableSet).835> - Для получения дополнительной информации об ABC см. модуль [`abc`](https://python-all.ru/2.7/library/abc.html#module-abc) и .836