collections.md
1> **Источник:** https://python-all.ru/3.0/library/collections.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `collections` – Контейнерные типы данных89Этот модуль реализует высокопроизводительные контейнерные типы данных. На данный момент есть два типа: [`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) неудобно.1011Специализированные контейнеры, предоставляемые этим модулем, являются альтернативой встроенным контейнерам общего назначения 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).1213Помимо контейнеров, модуль collections предоставляет несколько ABC (абстрактных базовых классов), которые можно использовать для проверки, поддерживает ли класс определённый интерфейс, например, является ли он хешируемым или отображением. Некоторые из них также можно использовать как классы-примеси (mixin).1415## ABC – абстрактные базовые классы1617Модуль collections предоставляет следующие ABC:1819| ABC | Наследует | Абстрактные методы | Методы-примеси |20| --- | --- | --- | --- |21| `Container` | | `__contains__` | |22| `Hashable` | | `__hash__` | |23| `Iterable` | | `__iter__` | |24| `Iterator` | `Iterable` | `__next__` | `__iter__` |25| `Sized` | | `__len__` | |26| `Callable` | | `__call__` | |27| `Sequence` | `Sized`, `Iterable`, `Container` | `__getitem__` | `__contains__`. `__iter__`, `__reversed__`. `index` и `count` |28| `MutableSequence` | `Sequence` | `__setitem__` `__delitem__`, и `insert` | Унаследованные методы Sequence и `append`, `reverse`, `extend`, `pop`, `remove` и `__iadd__` |29| `Set` | `Sized`, `Iterable`, `Container` | | `__le__`, `__lt__`, `__eq__`, `__ne__`, `__gt__`, `__ge__`, `__and__`, `__or__` `__sub__`, `__xor__` и `isdisjoint` |30| `MutableSet` | `Set` | `add` и `discard` | Наследуемые методы Set и `clear`, `pop`, `remove`, `__ior__`, `__iand__`, `__ixor__` и `__isub__` |31| `Mapping` | `Sized`, `Iterable`, `Container` | `__getitem__` | `__contains__`, `keys`, `items`, `values`, `get`, `__eq__` и `__ne__` |32| `MutableMapping` | `Mapping` | `__setitem__` и `__delitem__` | Наследуемые методы Mapping и `pop`, `popitem`, `clear`, `update`, и `setdefault` |33| `MappingView` | `Sized` | | `__len__` |34| `KeysView` | `MappingView`, `Set` | | `__contains__`, `__iter__` |35| `ItemsView` | `MappingView`, `Set` | | `__contains__`, `__iter__` |36| `ValuesView` | `MappingView` | | `__contains__`, `__iter__` |3738Эти ABC позволяют проверять, предоставляют ли классы или их экземпляры определённую функциональность, например:3940```python41size = None42if isinstance(myvar, collections.Sized):43 size = len(myvar)44```4546Несколько 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()`4748```python49class ListBasedSet(collections.Set):50 ''' Alternate set implementation favoring space over speed51 and not requiring the set elements to be hashable. '''52 def __init__(self, iterable):53 self.elements = lst = []54 for value in iterable:55 if value not in lst:56 lst.append(value)57 def __iter__(self):58 return iter(self.elements)59 def __contains__(self, value):60 return value in self.elements61 def __len__(self):62 return len(self.elements)6364s1 = ListBasedSet('abcdef')65s2 = ListBasedSet('defghi')66overlap = s1 & s2 # The __and__() method is supported automatically67```6869Примечания по использованию `Set` и `MutableSet` в качестве примеси:70711. Поскольку некоторые операции над множествами создают новые множества, методам примеси по умолчанию нужен способ создавать новые экземпляры из итерируемого объекта. Предполагается, что конструктор класса имеет сигнатуру вида `ClassName(iterable)`. Это предположение вынесено во внутренний метод класса `_from_iterable()`, который вызывает `cls(iterable)` для создания нового множества. Если примесь `Set` используется в классе с другой сигнатурой конструктора, необходимо переопределить `from_iterable()` методом класса, который может создавать новые экземпляры из итерируемого аргумента.722. Чтобы переопределить операции сравнения (предположительно для скорости, так как семантика фиксирована), переопределите [`__le__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__le__), и остальные операции автоматически последуют этому примеру.733. Примесь `Set` предоставляет метод `_hash()` для вычисления хеш-значения множества; однако [`__hash__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__hash__) не определён, поскольку не все множества хешируемы или неизменяемы. Чтобы добавить хешируемость множеству с помощью примесей, наследуйтесь от обоих `Set()` и `Hashable()`, затем определите `__hash__ = Set._hash`.7475(Подробнее об ABC см. модуль [`abc`](https://python-all.ru/3.0/library/abc.html#module-abc) и [**PEP 3119**](https://python-all.ru/3.0/library/collections.html).)7677## объекты [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque)7879#### `[collections.deque]class collections.deque([iterable[, maxlen]])`8081Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.0/library/collections.html#collections.deque.append)) данными из *iterable*. Если *iterable* не указан, новый deque пуст.8283Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.8485Хотя объекты [`list`](https://python-all.ru/3.0/library/functions.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и несут затраты памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.8687Если *maxlen* не указан или равен *None*, deque могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque с ограниченной длиной заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.8889Объекты deque поддерживают следующие методы:9091#### `[collections.deque.append]append(x)`9293Добавляет9495*x*9697в правую часть deque.9899#### `[collections.deque.appendleft]appendleft(x)`100101Добавляет102103*x*104105в левую часть deque.106107#### `[collections.deque.clear]clear()`108109Удаляет все элементы из deque, после чего его длина равна 0.110111#### `[collections.deque.extend]extend(iterable)`112113Расширяет правую часть deque, добавляя элементы из итерируемого объекта.114115#### `[collections.deque.extendleft]extendleft(iterable)`116117Расширяет левую часть deque, добавляя элементы из118119*итерируемого объекта*120121. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.122123#### `[collections.deque.pop]pop()`124125Удаляет и возвращает элемент с правой стороны deque. Если элементов нет, возбуждает126127[`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError)128129.130131#### `[collections.deque.popleft]popleft()`132133Удаляет и возвращает элемент с левой стороны deque. Если элементов нет, возбуждает134135[`IndexError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.IndexError)136137.138139#### `[collections.deque.remove]remove(value)`140141Удаляет первое вхождение142143*value*144145. Если не найдено, возбуждает146147[`ValueError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.ValueError)148149.150151#### `[collections.deque.rotate]rotate(n)`152153Поворачивает deque на154155*n*156157шагов вправо. Если158159*n*160161отрицательно, поворачивает влево. Поворот на один шаг вправо эквивалентен:162163`d.appendleft(d.pop())`164165.166167В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `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) в середине. Для быстрого произвольного доступа используйте списки.168169Пример:170171```python172>>> from collections import deque173>>> d = deque('ghi') # создать новый deque с тремя элементами174>>> for elem in d: # обход элементов deque175... print(elem.upper())176G177H178I179180>>> d.append('j') # добавить новый элемент справа181>>> d.appendleft('f') # добавить новый элемент слева182>>> d # показать представление deque183deque(['f', 'g', 'h', 'i', 'j'])184185>>> d.pop() # вернуть и удалить правый элемент186'j'187>>> d.popleft() # вернуть и удалить левый элемент188'f'189>>> list(d) # вывести содержимое deque190['g', 'h', 'i']191>>> d[0] # посмотреть левый элемент192'g'193>>> d[-1] # посмотреть правый элемент194'i'195196>>> list(reversed(d)) # вывести содержимое deque в обратном порядке197['i', 'h', 'g']198>>> 'h' in d # поиск в deque199True200>>> d.extend('jkl') # добавить несколько элементов за раз201>>> d202deque(['g', 'h', 'i', 'j', 'k', 'l'])203>>> d.rotate(1) # поворот вправо204>>> d205deque(['l', 'g', 'h', 'i', 'j', 'k'])206>>> d.rotate(-1) # поворот влево207>>> d208deque(['g', 'h', 'i', 'j', 'k', 'l'])209210>>> deque(reversed(d)) # создать новую deque в обратном порядке211deque(['l', 'k', 'j', 'i', 'h', 'g'])212>>> d.clear() # очистить deque213>>> d.pop() # невозможно извлечь элемент из пустой deque214Traceback (most recent call last):215 File "<pyshell#6>", line 1, in -toplevel-216 d.pop()217IndexError: pop from an empty deque218219>>> d.extendleft('abc') # extendleft() меняет порядок ввода на обратный220>>> d221deque(['c', 'b', 'a'])222```223224### [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque) Рецепты225226В этом разделе рассматриваются различные подходы к работе с деками.227228Метод `rotate()` позволяет реализовать срезы и удаление для [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque). Например, чистая реализация на Python для `del d[n]` использует метод `rotate()` для переноса элементов, которые нужно извлечь, в нужную позицию:229230```python231def delete_nth(d, n):232 d.rotate(-n)233 d.popleft()234 d.rotate(n)235```236237Чтобы реализовать срезы для [`deque`](https://python-all.ru/3.0/library/collections.html#collections.deque), используйте аналогичный подход, применяя `rotate()` для перемещения целевого элемента к левой стороне deque. Удалите старые записи с помощью `popleft()`, добавьте новые с помощью `extend()`, а затем обратите вращение. С небольшими вариациями этого подхода легко реализовать стековые манипуляции в стиле Forth, такие как `dup`, `drop`, `swap`, `over`, `pick`, `rot` и `roll`.238239Алгоритмы многоэтапного сокращения данных можно кратко выразить и эффективно реализовать, извлекая элементы с помощью многократных вызовов `popleft()`, применяя функцию сокращения и вызывая `append()` для добавления результата обратно в deque.240241Например, построение сбалансированного бинарного дерева из вложенных списков требует объединения двух соседних узлов в один путём группировки их в список:242243```python244>>> def maketree(iterable):245... d = deque(iterable)246... while len(d) > 1:247... pair = [d.popleft(), d.popleft()]248... d.append(pair)249... return list(d)250...251>>> print(maketree('abcdefgh'))252[[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]]253```254255Двусторонние очереди с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:256257```python258def tail(filename, n=10):259 'Return the last n lines of a file'260 return deque(open(filename), n)261```262263## [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) объекты264265#### `[collections.defaultdict]class collections.defaultdict([default_factory[, ...]])`266267Возвращает новый объект, похожий на словарь. [`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) и здесь не документируется.268269Первый аргумент задаёт начальное значение для атрибута [`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), включая именованные аргументы.270271Объекты [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict):272273#### `[collections.defaultdict.__missing__]__missing__(key)`274275Если атрибут [`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* в качестве аргумента.276277Если [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов, чтобы предоставить значение по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.278279Если вызов [`default_factory`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.default_factory) возбуждает исключение, это исключение распространяется без изменений.280281Этот метод вызывается методом [`__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__).282283Объекты [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) поддерживают следующую переменную экземпляра:284285#### `[collections.defaultdict.default_factory]default_factory`286287Этот атрибут используется методом288289[`__missing__()`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict.__missing__)290291; он инициализируется из первого аргумента конструктора, если он присутствует, или292293`None`294295, если отсутствует.296297### [`defaultdict`](https://python-all.ru/3.0/library/collections.html#collections.defaultdict) Примеры298299Используя [`list`](https://python-all.ru/3.0/library/functions.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:300301```python302>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]303>>> d = defaultdict(list)304>>> for k, v in s:305... d[k].append(v)306...307>>> d.items()308[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]309```310311Когда ключ встречается впервые, его ещё нет в отображении; поэтому запись автоматически создаётся с помощью функции `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):312313```python314>>> d = {}315>>> for k, v in s:316... d.setdefault(k, []).append(v)317...318>>> d.items()319[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]320```321322Установка `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) полезным для подсчёта (как мешок или мультимножество в других языках):323324```python325>>> s = 'mississippi'326>>> d = defaultdict(int)327>>> for k in s:328... d[k] += 1329...330>>> d.items()331[('i', 4), ('p', 2), ('s', 4), ('m', 1)]332```333334Когда буква встречается впервые, она отсутствует в отображении, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.0/library/functions.html#int), чтобы получить нулевое значение по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.335336Функция [`int()`](https://python-all.ru/3.0/library/functions.html#int), которая всегда возвращает ноль, – всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):337338```python339>>> def constant_factory(value):340... return lambda: value341>>> d = defaultdict(constant_factory('<missing>'))342>>> d.update(name='John', action='ran')343>>> '%(name)s %(action)s to %(object)s' % d344'John ran to <missing>'345```346347Установка `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) полезным для построения словаря множеств:348349```python350>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]351>>> d = defaultdict(set)352>>> for k, v in s:353... d[k].add(v)354...355>>> d.items()356[('blue', set([2, 4])), ('red', set([1, 3]))]357```358359## [`namedtuple()`](https://python-all.ru/3.0/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями360361Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.362363#### `[collections.namedtuple]collections.namedtuple(typename, field_names[, verbose])`364365Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежу, поля которых доступны через обращение к атрибутам, а также индексируемы и итерируемы. Экземпляры подкласса также имеют полезную docstring (с именем типа и полями) и полезный метод [`__repr__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.366367Параметр *field\_names* может быть строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`. Как вариант, *field\_names* может быть последовательностью строк, например `['x', 'y']`.368369В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и подчёркиваний, но не начинаются с цифры или подчёркивания и не могут быть [`ключевым словом`](https://python-all.ru/3.0/library/keyword.html#module-keyword), таким как *class*, *for*, *return*, *global*, *pass* или *raise*.370371Если *verbose* равно true, определение класса выводится непосредственно перед его созданием.372373Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.374375Пример:376377```python378>>> Point = namedtuple('Point', 'x y', verbose=True)379class Point(tuple):380 'Point(x, y)'381382 __slots__ = ()383384 _fields = ('x', 'y')385386 def __new__(cls, x, y):387 return tuple.__new__(cls, (x, y))388389 @classmethod390 def _make(cls, iterable, new=tuple.__new__, len=len):391 'Make a new Point object from a sequence or iterable'392 result = new(cls, iterable)393 if len(result) != 2:394 raise TypeError('Expected 2 arguments, got %d' % len(result))395 return result396397 def __repr__(self):398 return 'Point(x=%r, y=%r)' % self399400 def _asdict(t):401 'Return a new dict which maps field names to their values'402 return {'x': t[0], 'y': t[1]}403404 def _replace(self, **kwds):405 'Return a new Point object replacing specified fields with new values'406 result = self._make(map(kwds.pop, ('x', 'y'), self))407 if kwds:408 raise ValueError('Got unexpected field names: %r' % kwds.keys())409 return result410411 def __getnewargs__(self):412 return tuple(self)413414 x = property(itemgetter(0))415 y = property(itemgetter(1))416417>>> p = Point(11, y=22) # создать экземпляр с позиционными или именованными аргументами418>>> p[0] + p[1] # доступен по индексу, как обычный кортеж (11, 22)41933420>>> x, y = p # распаковывается как обычный кортеж421>>> x, y422(11, 22)423>>> p.x + p.y # поля также доступны по имени42433425>>> p # читаемое __repr__ в стиле name=value426Point(x=11, y=22)427```428429Именованные кортежи особенно полезны для присвоения имён полям кортежам результатов, возвращаемым модулями [`csv`](https://python-all.ru/3.0/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.0/library/sqlite3.html#module-sqlite3):430431```python432EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')433434import csv435for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):436 print(emp.name, emp.title)437438import sqlite3439conn = sqlite3.connect('/companydata')440cursor = conn.cursor()441cursor.execute('SELECT name, age, title, department, paygrade FROM employees')442for emp in map(EmployeeRecord._make, cursor.fetchall()):443 print(emp.name, emp.title)444```445446В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и один атрибут. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.447448#### `[collections.somenamedtuple._make]somenamedtuple._make(iterable)`449450Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.451452```python453>>> t = [11, 22]454>>> Point._make(t)455Point(x=11, y=22)456```457458#### `[collections.somenamedtuple._asdict]somenamedtuple._asdict()`459460Возвращает новый словарь, который отображает имена полей в соответствующие значения:461462```python463>>> p._asdict()464{'x': 11, 'y': 22}465```466467#### `[collections.somenamedtuple._replace]somenamedtuple._replace(kwargs)`468469Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:470471```python472>>> p = Point(x=11, y=22)473>>> p._replace(x=33)474Point(x=33, y=22)475476>>> for partnum, record in inventory.items():477... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())478```479480#### `[collections.somenamedtuple._fields]somenamedtuple._fields`481482Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.483484```python485>>> p._fields # просмотреть имена полей486('x', 'y')487488>>> Color = namedtuple('Color', 'red green blue')489>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)490>>> Pixel(11, 22, 128, 255, 0)491Pixel(x=11, y=22, red=128, green=255, blue=0)492```493494Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.0/library/functions.html#getattr):495496```python497>>> getattr(p, 'x')49811499```500501Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [*Распаковка списков аргументов*](https://python-all.ru/3.0/tutorial/controlflow.html#tut-unpacking-arguments)):502503```python504>>> d = {'x': 11, 'y': 22}505>>> Point(**d)506Point(x=11, y=22)507```508509Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:510511> ```python512> >>> class Point(namedtuple('Point', 'x y')):513> ... __slots__ = ()514> ... @property515> ... def hypot(self):516> ... return (self.x ** 2 + self.y ** 2) ** 0.5517> ... def __str__(self):518> ... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)519> ```520>521> ```python522> >>> for p in Point(3, 4), Point(14, 5/7):523> ... print(p)524> Point: x= 3.000 y= 4.000 hypot= 5.000525> Point: x=14.000 y= 0.714 hypot=14.018526> ```527528Показанный выше подкласс устанавливает `__slots__` в пустой кортеж. Это позволяет снизить требования к памяти за счёт предотвращения создания словарей экземпляров.529530Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа на основе атрибута `_fields`:531532```python533>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))534```535536Значения по умолчанию можно реализовать, используя `_replace()` для настройки экземпляра-прототипа:537538```python539>>> Account = namedtuple('Account', 'owner balance transaction_count')540>>> default_account = Account('<owner name>', 0.0, 0)541>>> johns_account = default_account._replace(owner='John')542```543544Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простое объявление класса:545546```python547>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))548>>> Status.open, Status.pending, Status.closed549(0, 1, 2)550>>> class Status:551... open, pending, closed = range(3)552```553554> **См. также**555>556> [Рецепт именованного кортежа](https://python-all.ru/3.0/library/collections.html) адаптирован для Python 2.4.557558## [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) объекты559560Класс [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов словаря. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`dict`](https://python-all.ru/3.0/library/stdtypes.html#dict); однако с этим классом может быть проще работать, потому что базовый словарь доступен как атрибут.561562#### `[collections.UserDict]class collections.UserDict([initialdata])`563564Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, который доступен через атрибут565566[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserDict.data)567568объектов569570[`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict)571572. Если передан573574*initialdata*575576, то577578[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserDict.data)579580инициализируется его содержимым; обратите внимание, что ссылка на581582*initialdata*583584не сохраняется, что позволяет использовать его для других целей.585586В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict) предоставляют следующий атрибут:587588#### `[collections.UserDict.data]UserDict.data`589590Реальный словарь, используемый для хранения содержимого класса591592[`UserDict`](https://python-all.ru/3.0/library/collections.html#collections.UserDict)593594.595596## [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) объекты597598Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.599600Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`list`](https://python-all.ru/3.0/library/functions.html#list); однако с этим классом может быть проще работать, потому что базовый список доступен как атрибут.601602#### `[collections.UserList]class collections.UserList([list])`603604Класс, имитирующий список. Содержимое экземпляра хранится в обычном списке, который доступен через атрибут605606[`data`](https://python-all.ru/3.0/library/collections.html#collections.UserList.data)607608объектов609610[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)611612. Содержимое экземпляра изначально устанавливается в копию613614*list*615616, по умолчанию пустой список617618`[]`619620.621622*list*623624может быть любым итерируемым объектом, например, настоящим списком Python или объектом625626[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)627628.629630В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) предоставляют следующий атрибут:631632#### `[collections.UserList.data]UserList.data`633634Настоящий объект635636[`list`](https://python-all.ru/3.0/library/functions.html#list)637638, используемый для хранения содержимого класса639640[`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList)641642.643644**Требования к наследованию:** Подклассы [`UserList`](https://python-all.ru/3.0/library/collections.html#collections.UserList) должны предоставлять конструктор, который можно вызывать без аргументов или с одним аргументом. Операции со списками, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром, который является объектом последовательности, используемым в качестве источника данных.645646Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.647648## [`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString) объекты649650Класс [`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString) действует как обёртка вокруг строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`str`](https://python-all.ru/3.0/library/functions.html#str); однако с этим классом может быть проще работать, потому что базовая строка доступна как атрибут.651652#### `[collections.UserString]class collections.UserString([sequence])`653654Класс, имитирующий строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, который доступен через атрибут655656`data`657658объектов659660[`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString)661662. Содержимое экземпляра изначально устанавливается в копию663664*sequence*665666.667668*sequence*669670может быть экземпляром671672[`bytes`](https://python-all.ru/3.0/library/functions.html#bytes)673674,675676[`str`](https://python-all.ru/3.0/library/functions.html#str)677678,679680[`UserString`](https://python-all.ru/3.0/library/collections.html#collections.UserString)681682(или подклассом) или произвольной последовательностью, которая может быть преобразована в строку с помощью встроенной функции683684[`str()`](https://python-all.ru/3.0/library/functions.html#str)685686.687