> **Источник:** https://python-all.ru/3.0/library/collections.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# `collections` – Контейнерные типы данных

Этот модуль реализует высокопроизводительные контейнерные типы данных. На данный момент есть два типа: [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque) и [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict), а также одна фабричная функция типа данных – [`namedtuple()`](https://python-all.ru/3.0/library/collections.html#collections.namedtuple). Кроме того, модуль предоставляет классы [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) и [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList), которые могут быть полезны, когда непосредственное наследование от [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict) или [`list`](https://python-all.ru/3.0/library/functions.html#list) неудобно.

Специализированные контейнеры, предоставляемые этим модулем, являются альтернативой встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.0/library/functions.html#list), [`set`](https://python-all.ru/3.0/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.0/library/functions.html#tuple).

Помимо контейнеров, модуль collections предоставляет несколько ABC (абстрактных базовых классов), которые можно использовать для проверки, поддерживает ли класс определённый интерфейс, например, является ли он хешируемым или отображением. Некоторые из них также можно использовать как классы-примеси (mixin).

## ABC – абстрактные базовые классы

Модуль collections предоставляет следующие ABC:

| ABC | Наследует | Абстрактные методы | Методы-примеси |
| --- | --- | --- | --- |
| `Container` |  | `__contains__` |  |
| `Hashable` |  | `__hash__` |  |
| `Iterable` |  | `__iter__` |  |
| `Iterator` | `Iterable` | `__next__` | `__iter__` |
| `Sized` |  | `__len__` |  |
| `Callable` |  | `__call__` |  |
| `Sequence` | `Sized`, `Iterable`, `Container` | `__getitem__` | `__contains__`. `__iter__`, `__reversed__`. `index` и `count` |
| `MutableSequence` | `Sequence` | `__setitem__` `__delitem__`, и `insert` | Унаследованные методы Sequence и `append`, `reverse`, `extend`, `pop`, `remove` и `__iadd__` |
| `Set` | `Sized`, `Iterable`, `Container` |  | `__le__`, `__lt__`, `__eq__`, `__ne__`, `__gt__`, `__ge__`, `__and__`, `__or__` `__sub__`, `__xor__` и `isdisjoint` |
| `MutableSet` | `Set` | `add` и `discard` | Наследуемые методы Set и `clear`, `pop`, `remove`, `__ior__`, `__iand__`, `__ixor__` и `__isub__` |
| `Mapping` | `Sized`, `Iterable`, `Container` | `__getitem__` | `__contains__`, `keys`, `items`, `values`, `get`, `__eq__` и `__ne__` |
| `MutableMapping` | `Mapping` | `__setitem__` и `__delitem__` | Наследуемые методы Mapping и `pop`, `popitem`, `clear`, `update`, и `setdefault` |
| `MappingView` | `Sized` |  | `__len__` |
| `KeysView` | `MappingView`, `Set` |  | `__contains__`, `__iter__` |
| `ItemsView` | `MappingView`, `Set` |  | `__contains__`, `__iter__` |
| `ValuesView` | `MappingView` |  | `__contains__`, `__iter__` |

Эти ABC позволяют проверять, предоставляют ли классы или их экземпляры определённую функциональность, например:

```python
size = None
if isinstance(myvar, collections.Sized):
    size = len(myvar)
```

Несколько ABC также полезны в качестве примесей (mixins), упрощающих разработку классов, поддерживающих контейнерные API. Например, чтобы написать класс, поддерживающий полный API `Set`, достаточно предоставить три базовых абстрактных метода: [`__contains__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__contains__), [`__iter__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__iter__) и [`__len__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__len__). ABC предоставляет остальные методы, такие как [`__and__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__and__) и `isdisjoint()`

```python
class ListBasedSet(collections.Set):
     ''' Alternate set implementation favoring space over speed
         and not requiring the set elements to be hashable. '''
     def __init__(self, iterable):
         self.elements = lst = []
         for value in iterable:
             if value not in lst:
                 lst.append(value)
     def __iter__(self):
         return iter(self.elements)
     def __contains__(self, value):
         return value in self.elements
     def __len__(self):
         return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2            # The __and__() method is supported automatically
```

Примечания по использованию `Set` и `MutableSet` в качестве примеси:

1. Поскольку некоторые операции над множествами создают новые множества, методам примеси по умолчанию нужен способ создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида `ClassName(iterable)`. Это предположение вынесено во внутренний метод класса `_from_iterable()`, который вызывает `cls(iterable)` для создания нового множества. Если примесь `Set` используется в классе с другой сигнатурой конструктора, необходимо переопределить `from_iterable()` методом класса, который может создавать новые экземпляры из итерируемого аргумента.
2. Чтобы переопределить операции сравнения (предположительно для скорости, так как семантика фиксирована), переопределите [`__le__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__le__), и остальные операции автоматически последуют этому примеру.
3. Примесь `Set` предоставляет метод `_hash()` для вычисления хеш-значения множества; однако [`__hash__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__hash__) не определён, поскольку не все множества хешируемы или неизменяемы. Чтобы добавить хешируемость множеству с помощью примесей, наследуйтесь от обоих `Set()` и `Hashable()`, затем определите `__hash__ = Set._hash`.

(Подробнее об ABC см. модуль [`abc`](https://python-all.ru/3.0/library/abc.html#module-abc) и [**PEP 3119**](https://python-all.ru/3.0/library/collections.html).)

## объекты [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque)

#### `[collections.deque]class collections.deque([iterable[, maxlen]])`

Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.0/library/collections.html#collections.deque.append)) данными из *iterable*. Если *iterable* не указан, новый deque пуст.

Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.

Хотя объекты [`list`](https://python-all.ru/3.0/library/functions.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и несут затраты памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.

Если *maxlen* не указан или равен *None*, deque могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque с ограниченной длиной заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.

Объекты deque поддерживают следующие методы:

#### `[collections.deque.append]append(x)`

Добавляет

*x*

в правую часть deque.

#### `[collections.deque.appendleft]appendleft(x)`

Добавляет

*x*

в левую часть deque.

#### `[collections.deque.clear]clear()`

Удаляет все элементы из deque, после чего его длина равна 0.

#### `[collections.deque.extend]extend(iterable)`

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

#### `[collections.deque.extendleft]extendleft(iterable)`

Расширяет левую часть deque, добавляя элементы из

*итерируемого объекта*

. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.

#### `[collections.deque.pop]pop()`

Удаляет и возвращает элемент с правой стороны deque. Если элементов нет, возбуждает

[`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError)

.

#### `[collections.deque.popleft]popleft()`

Удаляет и возвращает элемент с левой стороны deque. Если элементов нет, возбуждает

[`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError)

.

#### `[collections.deque.remove]remove(value)`

Удаляет первое вхождение

*value*

. Если не найдено, возбуждает

[`ValueError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.ValueError)

.

#### `[collections.deque.rotate]rotate(n)`

Поворачивает deque на

*n*

шагов вправо. Если

*n*

отрицательно, поворачивает влево. Поворот на один шаг вправо эквивалентен:

`d.appendleft(d.pop())`

.

В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.0/reference/expressions.html#in) и доступ по индексу, например `d[-1]`. Индексированный доступ занимает O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.

Пример:

```python
>>> from collections import deque
>>> d = deque('ghi')                 # создать новый deque с тремя элементами
>>> for elem in d:                   # обход элементов deque
...     print(elem.upper())
G
H
I

>>> d.append('j')                    # добавить новый элемент справа
>>> d.appendleft('f')                # добавить новый элемент слева
>>> d                                # показать представление deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop()                          # вернуть и удалить правый элемент
'j'
>>> d.popleft()                      # вернуть и удалить левый элемент
'f'
>>> list(d)                          # вывести содержимое deque
['g', 'h', 'i']
>>> d[0]                             # посмотреть левый элемент
'g'
>>> d[-1]                            # посмотреть правый элемент
'i'

>>> list(reversed(d))                # вывести содержимое deque в обратном порядке
['i', 'h', 'g']
>>> 'h' in d                         # поиск в deque
True
>>> d.extend('jkl')                  # добавить несколько элементов за раз
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1)                      # поворот вправо
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> d.rotate(-1)                     # поворот влево
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d))               # создать новую deque в обратном порядке
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear()                        # очистить deque
>>> d.pop()                          # невозможно извлечь элемент из пустой deque
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in -toplevel-
    d.pop()
IndexError: pop from an empty deque

>>> d.extendleft('abc')              # extendleft() меняет порядок ввода на обратный
>>> d
deque(['c', 'b', 'a'])
```

### [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque) Рецепты

В этом разделе рассматриваются различные подходы к работе с деками.

Метод `rotate()` позволяет реализовать срезы и удаление для [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque). Например, чистая реализация на Python для `del d[n]` использует метод `rotate()` для переноса элементов, которые нужно извлечь, в нужную позицию:

```python
def delete_nth(d, n):
    d.rotate(-n)
    d.popleft()
    d.rotate(n)
```

Чтобы реализовать срезы для [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque), используйте аналогичный подход, применяя `rotate()` для перемещения целевого элемента к левой стороне deque. Удалите старые записи с помощью `popleft()`, добавьте новые с помощью `extend()`, а затем обратите вращение. С небольшими вариациями этого подхода легко реализовать стековые манипуляции в стиле Forth, такие как `dup`, `drop`, `swap`, `over`, `pick`, `rot` и `roll`.

Алгоритмы многоэтапного сокращения данных можно кратко выразить и эффективно реализовать, извлекая элементы с помощью многократных вызовов `popleft()`, применяя функцию сокращения и вызывая `append()` для добавления результата обратно в deque.

Например, построение сбалансированного бинарного дерева из вложенных списков требует объединения двух соседних узлов в один путём группировки их в список:

```python
>>> def maketree(iterable):
...     d = deque(iterable)
...     while len(d) > 1:
...         pair = [d.popleft(), d.popleft()]
...         d.append(pair)
...     return list(d)
...
>>> print(maketree('abcdefgh'))
[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]
```

Двусторонние очереди с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:

```python
def tail(filename, n=10):
    'Return the last n lines of a file'
    return deque(open(filename), n)
```

## [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) объекты

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

Возвращает новый объект, похожий на словарь. [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность совпадает с классом [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict) и здесь не документируется.

Первый аргумент задаёт начальное значение для атрибута [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory); по умолчанию `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict), включая именованные аргументы.

Объекты [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict):

#### `[collections.defaultdict.__missing__]__missing__(key)`

Если атрибут [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory) равен `None`, это возбуждает исключение [`KeyError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.KeyError) с *key* в качестве аргумента.

Если [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов, чтобы предоставить значение по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.

Если вызов [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory) возбуждает исключение, это исключение распространяется без изменений.

Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict), когда запрошенный ключ не найден; то, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__getitem__).

Объекты [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) поддерживают следующую переменную экземпляра:

#### `[collections.defaultdict.default_factory]default_factory`

Этот атрибут используется методом

[`__missing__()`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.__missing__)

; он инициализируется из первого аргумента конструктора, если он присутствует, или

`None`

, если отсутствует.

### [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) Примеры

Используя [`list`](https://python-all.ru/3.0/library/functions.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:

```python
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
```

Когда ключ встречается впервые, его ещё нет в отображении; поэтому запись автоматически создаётся с помощью функции `default_factory`, которая возвращает пустой [`list`](https://python-all.ru/3.0/library/functions.html#list). Затем операция `list.append()` добавляет значение в новый список. При повторной встрече ключа поиск происходит обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет ещё одно значение в список. Этот метод проще и быстрее, чем эквивалентный приём с [`dict.setdefault()`](https://python-all.ru/3.0/library/stdtypes.html#dict.setdefault):

```python
>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
```

Установка `default_factory` в [`int`](https://python-all.ru/3.0/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) полезным для подсчёта (как мешок или мультимножество в других языках):

```python
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]
```

Когда буква встречается впервые, она отсутствует в отображении, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.0/library/functions.html#int), чтобы получить нулевое значение по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.

Функция [`int()`](https://python-all.ru/3.0/library/functions.html#int), которая всегда возвращает ноль, – всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):

```python
>>> def constant_factory(value):
...     return lambda: value
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'
```

Установка `default_factory` в [`set`](https://python-all.ru/3.0/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) полезным для построения словаря множеств:

```python
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> d.items()
[('blue', set([2, 4])), ('red', set([1, 3]))]
```

## [`namedtuple()`](https://python-all.ru/3.0/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями

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

#### `[collections.namedtuple]collections.namedtuple(typename, field_names[, verbose])`

Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежу, поля которых доступны через обращение к атрибутам, а также индексируемы и итерируемы. Экземпляры подкласса также имеют полезную docstring (с именем типа и полями) и полезный метод [`__repr__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.

Параметр *field\_names* может быть строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`. Как вариант, *field\_names* может быть последовательностью строк, например `['x', 'y']`.

В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и подчёркиваний, но не начинаются с цифры или подчёркивания и не могут быть [`ключевым словом`](https://python-all.ru/3.0/library/keyword.html#module-keyword), таким как *class*, *for*, *return*, *global*, *pass* или *raise*.

Если *verbose* равно true, определение класса выводится непосредственно перед его созданием.

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

Пример:

```python
>>> Point = namedtuple('Point', 'x y', verbose=True)
class Point(tuple):
        'Point(x, y)'

        __slots__ = ()

        _fields = ('x', 'y')

        def __new__(cls, x, y):
            return tuple.__new__(cls, (x, y))

        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new Point object from a sequence or iterable'
            result = new(cls, iterable)
            if len(result) != 2:
                raise TypeError('Expected 2 arguments, got %d' % len(result))
            return result

        def __repr__(self):
            return 'Point(x=%r, y=%r)' % self

        def _asdict(t):
            'Return a new dict which maps field names to their values'
            return {'x': t[0], 'y': t[1]}

        def _replace(self, **kwds):
            'Return a new Point object replacing specified fields with new values'
            result = self._make(map(kwds.pop, ('x', 'y'), self))
            if kwds:
                raise ValueError('Got unexpected field names: %r' % kwds.keys())
            return result

        def __getnewargs__(self):
            return tuple(self)

        x = property(itemgetter(0))
        y = property(itemgetter(1))

>>> p = Point(11, y=22)     # создать экземпляр с позиционными или именованными аргументами
>>> p[0] + p[1]             # доступен по индексу, как обычный кортеж (11, 22)
33
>>> x, y = p                # распаковывается как обычный кортеж
>>> x, y
(11, 22)
>>> p.x + p.y               # поля также доступны по имени
33
>>> p                       # читаемое __repr__ в стиле name=value
Point(x=11, y=22)
```

Именованные кортежи особенно полезны для присвоения имён полям кортежам результатов, возвращаемым модулями [`csv`](https://python-all.ru/3.0/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.0/library/sqlite3.html#module-sqlite3):

```python
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')

import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
    print(emp.name, emp.title)
```

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

#### `[collections.somenamedtuple._make]somenamedtuple._make(iterable)`

Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.

```python
>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
```

#### `[collections.somenamedtuple._asdict]somenamedtuple._asdict()`

Возвращает новый словарь, который отображает имена полей в соответствующие значения:

```python
>>> p._asdict()
{'x': 11, 'y': 22}
```

#### `[collections.somenamedtuple._replace]somenamedtuple._replace(kwargs)`

Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:

```python
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)

>>> for partnum, record in inventory.items():
...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
```

#### `[collections.somenamedtuple._fields]somenamedtuple._fields`

Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.

```python
>>> p._fields            # просмотреть имена полей
('x', 'y')

>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
```

Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.0/library/functions.html#getattr):

```python
>>> getattr(p, 'x')
11
```

Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [*Распаковка списков аргументов*](https://python-all.ru/3.0/tutorial/controlflow.html#tut-unpacking-arguments)):

```python
>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)
```

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

> ```python
> >>> class Point(namedtuple('Point', 'x y')):
> ...     __slots__ = ()
> ...     @property
> ...     def hypot(self):
> ...         return (self.x ** 2 + self.y ** 2) ** 0.5
> ...     def __str__(self):
> ...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)
> ```
>
> ```python
> >>> for p in Point(3, 4), Point(14, 5/7):
> ...     print(p)
> Point: x= 3.000  y= 4.000  hypot= 5.000
> Point: x=14.000  y= 0.714  hypot=14.018
> ```

Показанный выше подкласс устанавливает `__slots__` в пустой кортеж. Это позволяет снизить требования к памяти за счёт предотвращения создания словарей экземпляров.

Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа на основе атрибута `_fields`:

```python
>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))
```

Значения по умолчанию можно реализовать, используя `_replace()` для настройки экземпляра-прототипа:

```python
>>> Account = namedtuple('Account', 'owner balance transaction_count')
>>> default_account = Account('<owner name>', 0.0, 0)
>>> johns_account = default_account._replace(owner='John')
```

Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простое объявление класса:

```python
>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))
>>> Status.open, Status.pending, Status.closed
(0, 1, 2)
>>> class Status:
...     open, pending, closed = range(3)
```

> **См. также**
>
> [Рецепт именованного кортежа](https://python-all.ru/3.0/library/collections.html) адаптирован для Python 2.4.

## [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) объекты

Класс [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов словаря. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict); однако с этим классом может быть проще работать, потому что базовый словарь доступен как атрибут.

#### `[collections.UserDict]class collections.UserDict([initialdata])`

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

[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserDict.data)

объектов

[`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict)

. Если передан

*initialdata*

, то

[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserDict.data)

инициализируется его содержимым; обратите внимание, что ссылка на

*initialdata*

не сохраняется, что позволяет использовать его для других целей.

В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) предоставляют следующий атрибут:

#### `[collections.UserDict.data]UserDict.data`

Реальный словарь, используемый для хранения содержимого класса

[`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict)

.

## [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) объекты

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

Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`list`](https://python-all.ru/3.0/library/functions.html#list); однако с этим классом может быть проще работать, потому что базовый список доступен как атрибут.

#### `[collections.UserList]class collections.UserList([list])`

Класс, имитирующий список. Содержимое экземпляра хранится в обычном списке, который доступен через атрибут

[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserList.data)

объектов

[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)

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

*list*

, по умолчанию пустой список

`[]`

.

*list*

может быть любым итерируемым объектом, например, настоящим списком Python или объектом

[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)

.

В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) предоставляют следующий атрибут:

#### `[collections.UserList.data]UserList.data`

Настоящий объект

[`list`](https://python-all.ru/3.0/library/functions.html#list)

, используемый для хранения содержимого класса

[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)

.

**Требования к наследованию:** Подклассы [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) должны предоставлять конструктор, который можно вызывать без аргументов или с одним аргументом. Операции со списками, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром, который является объектом последовательности, используемым в качестве источника данных.

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

## [`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString) объекты

Класс [`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString) действует как обёртка вокруг строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`str`](https://python-all.ru/3.0/library/functions.html#str); однако с этим классом может быть проще работать, потому что базовая строка доступна как атрибут.

#### `[collections.UserString]class collections.UserString([sequence])`

Класс, имитирующий строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, который доступен через атрибут

`data`

объектов

[`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString)

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

*sequence*

.

*sequence*

может быть экземпляром

[`bytes`](https://python-all.ru/3.0/library/functions.html#bytes)

,

[`str`](https://python-all.ru/3.0/library/functions.html#str)

,

[`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString)

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

[`str()`](https://python-all.ru/3.0/library/functions.html#str)

.
