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

collections.md

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

1> **Источник:** https://python-all.ru/3.6/library/collections.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 8.3. [`collections`](https://python-all.ru/3.6/library/collections.html#module-collections) – Контейнерные типы данных89**Исходный код:** [Lib/collections/\_\_init\_\_.py](https://python-all.ru/src/3.6/Lib/collections/__init__.py)1011---1213Этот модуль предоставляет специализированные типы данных-контейнеры в качестве альтернативы встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.6/library/stdtypes.html#list), [`set`](https://python-all.ru/3.6/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.6/library/stdtypes.html#tuple).1415| [`namedtuple()`](https://python-all.ru/3.6/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями |16| --- | --- |17| [`deque`](https://python-all.ru/3.6/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов |18| [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) | класс, подобный словарю, для создания единого представления нескольких отображений |19| [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов |20| [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей |21| [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений |22| [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict) | обёртка вокруг словарей для упрощения создания подклассов dict |23| [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList) | обёртка вокруг списков для упрощения создания подклассов list |24| [`UserString`](https://python-all.ru/3.6/library/collections.html#collections.UserString) | обёртка вокруг строк для упрощения создания подклассов str |2526Изменено в версии 3.3: Перенесены [Базовые абстрактные классы коллекций](https://python-all.ru/3.6/library/collections.abc.html#collections-abstract-base-classes) в модуль [`collections.abc`](https://python-all.ru/3.6/library/collections.abc.html#module-collections.abc). Для обратной совместимости они по-прежнему видны в этом модуле.2728## 8.3.1. [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) объекты2930Новое в версии 3.3.3132Класс [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) предназначен для быстрой связки нескольких отображений, чтобы их можно было рассматривать как единое целое. Часто он работает намного быстрее, чем создание нового словаря и выполнение нескольких вызовов [`update()`](https://python-all.ru/3.6/library/stdtypes.html#dict.update).3334Класс можно использовать для имитации вложенных областей видимости; он полезен в шаблонизаторах.3536#### `class collections.ChainMap(*maps)`3738[`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) группирует несколько словарей или других отображений вместе, создавая единое обновляемое представление. Если не указаны *maps*, создаётся один пустой словарь, так что новая цепочка всегда содержит как минимум одно отображение.3940Базовые отображения хранятся в списке. Этот список является открытым; к нему можно обращаться или изменять его через атрибут *maps*. Других состояний нет.4142При поиске последовательно просматриваются базовые отображения, пока не будет найден ключ. В отличие от этого, записи, обновления и удаления работают только с первым отображением.4344[`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) включает базовые отображения по ссылке. То есть, если одно из базовых отображений будет обновлено, эти изменения отразятся в [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap).4546Поддерживаются все обычные методы словаря. Кроме того, имеется атрибут *maps*, метод для создания новых подконтекстов и свойство для доступа ко всем отображениям, кроме первого:4748#### `maps`4950Обновляемый пользователем список отображений. Список упорядочен от первого просматриваемого к последнему. Это единственное сохраняемое состояние, и его можно изменять, чтобы менять порядок поиска отображений. Список всегда должен содержать хотя бы одно отображение.5152#### `new_child(m=None)`5354Возвращает новый объект [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap), содержащий новое отображение, за которым следуют все отображения из текущего экземпляра. Если указан `m`, он становится новым отображением в начале списка отображений; если не указан, используется пустой словарь, так что вызов `d.new_child()` эквивалентен следующему: `ChainMap({}, *d.maps)`. Этот метод используется для создания подконтекстов, которые можно обновлять, не изменяя значения ни в одном из родительских отображений.5556Изменено в версии 3.4: Был добавлен необязательный параметр `m`.5758#### `parents`5960Свойство, возвращающее новый [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap), содержащий все отображения из текущего экземпляра, кроме первого. Это полезно для пропуска первого отображения при поиске. Варианты использования аналогичны ключевому слову [`nonlocal`](https://python-all.ru/3.6/reference/simple_stmts.html#nonlocal), применяемому в [вложенных областях видимости](https://python-all.ru/3.6/glossary.html#term-nested-scope). Также они параллельны встроенной функции [`super()`](https://python-all.ru/3.6/library/functions.html#super). Ссылка на `d.parents` эквивалентна: `ChainMap(*d.maps[1:])`.6162> **См. также**63>64> - Класс [MultiContext](https://python-all.ru/3.6/library/collections.html) в пакете Enthought [CodeTools](https://python-all.ru/3.6/library/collections.html) имеет опции для поддержки записи в любое отображение в цепочке.65> - Класс [Context](https://python-all.ru/3.6/library/collections.html) в Django для шаблонов представляет собой цепочку отображений только для чтения. Он также поддерживает добавление и удаление контекстов, аналогично методу [`new_child()`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap.new_child) и свойству [`parents()`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap.parents).66> - Рецепт [Nested Contexts](https://python-all.ru/3.6/library/collections.html) содержит опции для управления тем, применяются ли записи и другие изменения только к первому отображению или к любому отображению в цепочке.67> - [Сильно упрощённая версия Chainmap только для чтения](https://python-all.ru/3.6/library/collections.html).6869### 8.3.1.1. [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) Примеры и рецепты7071В этом разделе показаны различные подходы к работе с цепочечными отображениями.7273Пример симуляции внутренней цепочки поиска Python:7475```python76import builtins77pylookup = ChainMap(locals(), globals(), vars(builtins))78```7980Пример, когда заданные пользователем аргументы командной строки имеют приоритет над переменными окружения, которые, в свою очередь, имеют приоритет над значениями по умолчанию:8182```python83import os, argparse8485defaults = {'color': 'red', 'user': 'guest'}8687parser = argparse.ArgumentParser()88parser.add_argument('-u', '--user')89parser.add_argument('-c', '--color')90namespace = parser.parse_args()91command_line_args = {k:v for k, v in vars(namespace).items() if v}9293combined = ChainMap(command_line_args, os.environ, defaults)94print(combined['color'])95print(combined['user'])96```9798Примеры шаблонов использования класса [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) для симуляции вложенных контекстов:99100```python101c = ChainMap()        # Создать корневой контекст102d = c.new_child()     # Создать вложенный дочерний контекст103e = c.new_child()     # Дочерний контекст c, независимый от d104e.maps[0]             # Словарь текущего контекста – как locals() в Python105e.maps[-1]            # Корневой контекст – как globals() в Python106e.parents             # Цепочка объемлющих контекстов – как nonlocals в Python107108d['x']                # Получить первый ключ в цепочке контекстов109d['x'] = 1            # Установить значение в текущем контексте110del d['x']            # Удалить из текущего контекста111list(d)               # Все вложенные значения112k in d                # Проверить все вложенные значения113len(d)                # Количество вложенных значений114d.items()             # Все вложенные элементы115dict(d)               # Развернуть в обычный словарь116```117118Класс [`ChainMap`](https://python-all.ru/3.6/library/collections.html#collections.ChainMap) выполняет обновления (запись и удаление) только в первом отображении цепочки, в то время как поиск просматривает всю цепочку. Однако, если требуется глубокая запись и удаление, легко создать подкласс, который обновляет ключи, найденные глубже в цепочке:119120```python121class DeepChainMap(ChainMap):122    'Variant of ChainMap that allows direct updates to inner scopes'123124    def __setitem__(self, key, value):125        for mapping in self.maps:126            if key in mapping:127                mapping[key] = value128                return129        self.maps[0][key] = value130131    def __delitem__(self, key):132        for mapping in self.maps:133            if key in mapping:134                del mapping[key]135                return136        raise KeyError(key)137138>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})139>>> d['lion'] = 'orange'         # обновить существующий ключ на два уровня ниже140>>> d['snake'] = 'red'           # новые ключи добавляются в самый верхний словарь141>>> del d['elephant']            # удалить существующий ключ на один уровень ниже142>>> d                            # отобразить результат143DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})144```145146## 8.3.2. [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) объекты147148Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:149150```python151>>> # Подсчитать вхождения слов в списке152>>> cnt = Counter()153>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:154...     cnt[word] += 1155>>> cnt156Counter({'blue': 3, 'red': 2, 'green': 1})157158>>> # Найти десять самых распространённых слов в «Гамлете»159>>> import re160>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())161>>> Counter(words).most_common(10)162[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),163 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]164```165166#### `class collections.Counter([iterable-or-mapping])`167168Класс [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) является подклассом [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict) для подсчёта хешируемых объектов. Это неупорядоченная коллекция, в которой элементы хранятся в качестве ключей словаря, а их количество – в качестве значений словаря. Количество может быть любым целым числом, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) похож на мешки или мультимножества в других языках.169170Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):171172```python173>>> c = Counter()                           # новый пустой счётчик174>>> c = Counter('gallahad')                 # новый счётчик из итерируемого объекта175>>> c = Counter({'red': 4, 'blue': 2})      # новый счётчик из отображения176>>> c = Counter(cats=4, dogs=8)             # новый счётчик из именованных аргументов177```178179Объекты Counter имеют интерфейс словаря, за исключением того, что они возвращают ноль для отсутствующих элементов вместо возбуждения [`KeyError`](https://python-all.ru/3.6/library/exceptions.html#KeyError):180181```python182>>> c = Counter(['eggs', 'ham'])183>>> c['bacon']                              # счёт отсутствующего элемента равен нулю1840185```186187Установка количества в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:188189```python190>>> c['sausage'] = 0                        # запись счётчика с нулевым значением191>>> del c['sausage']                        # del действительно удаляет запись192```193194Новое в версии 3.1.195196Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:197198#### `elements()`199200Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его счётчике. Элементы возвращаются в произвольном порядке. Если счётчик элемента меньше единицы, [`elements()`](https://python-all.ru/3.6/library/collections.html#collections.Counter.elements) игнорирует его.201202```python203>>> c = Counter(a=4, b=2, c=0, d=-2)204>>> sorted(c.elements())205['a', 'a', 'a', 'a', 'b', 'b']206```207208#### `most_common([n])`209210Возвращает список из *n* наиболее часто встречающихся элементов и их количества, от наиболее частых к наименее частым. Если *n* опущено или `None`, [`most_common()`](https://python-all.ru/3.6/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковыми количествами упорядочиваются произвольно:211212```python213>>> Counter('abracadabra').most_common(3)  214[('a', 5), ('r', 2), ('b', 2)]215```216217#### `subtract([iterable-or-mapping])`218219Элементы вычитаются из *итерируемого объекта* или из другого *отображения* (или счётчика). Подобно [`dict.update()`](https://python-all.ru/3.6/library/stdtypes.html#dict.update), но вычитает количества вместо замены. Как входные, так и выходные значения могут быть нулевыми или отрицательными.220221```python222>>> c = Counter(a=4, b=2, c=0, d=-2)223>>> d = Counter(a=1, b=2, c=3, d=4)224>>> c.subtract(d)225>>> c226Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})227```228229Новое в версии 3.2.230231Обычные методы словарей доступны для объектов [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter), за исключением двух, которые работают с счётчиками иначе.232233#### `fromkeys(iterable)`234235Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter).236237#### `update([iterable-or-mapping])`238239Элементы подсчитываются из *итерируемого объекта* или добавляются из другого *отображения* (или счётчика). Как и [`dict.update()`](https://python-all.ru/3.6/library/stdtypes.html#dict.update), но увеличивает счётчики вместо их замены. Кроме того, *итерируемый объект* должен быть последовательностью элементов, а не последовательностью `(key, value)` пар.240241Типичные приёмы работы с объектами [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter):242243```python244sum(c.values())                 # сумма всех значений245c.clear()                       # сбросить все значения246list(c)                         # список уникальных элементов247set(c)                          # преобразовать в множество248dict(c)                         # преобразовать в обычный словарь249c.items()                       # преобразовать в список пар (elem, cnt)250Counter(dict(list_of_pairs))    # создать из списка пар (элемент, кол-во)251c.most_common()[:-n-1:-1]       # n наименее частых элементов252+c                              # удалить нулевые и отрицательные значения253```254255Для объединения объектов [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) в мультимножества (счётчики с положительными количествами) предоставляется несколько математических операций. Сложение и вычитание комбинируют счётчики, складывая или вычитая количества соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих количеств. Каждая операция может принимать входные данные со знаковыми количествами, но в результате будут исключены значения с нулевыми или отрицательными количествами.256257```python258>>> c = Counter(a=3, b=1)259>>> d = Counter(a=1, b=2)260>>> c + d                       # сложение двух счётчиков: c[x] + d[x]261Counter({'a': 4, 'b': 3})262>>> c - d                       # вычитание (остаются только положительные значения)263Counter({'a': 2})264>>> c & d                       # пересечение: min(c[x], d[x]) 265Counter({'a': 1, 'b': 1})266>>> c | d                       # объединение: max(c[x], d[x])267Counter({'a': 3, 'b': 2})268```269270Унарное сложение и вычитание – это сокращения для добавления пустого счётчика или вычитания из пустого счётчика.271272```python273>>> c = Counter(a=2, b=-4)274>>> +c275Counter({'a': 2})276>>> -c277Counter({'b': 4})278```279280Новое в версии 3.3: Добавлена поддержка унарного плюса, унарного минуса и операций над мультимножествами на месте.281282> **Примечание**283>284> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.285>286> - Сам класс [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения должны быть числами, представляющими счётчики, но в поле значения *можно* хранить что угодно.287> - Метод `most_common()` требует только упорядочиваемости значений.288> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа будут работать, и отрицательные значения поддерживаются. То же самое верно для `update()` и `subtract()`, которые допускают отрицательные и нулевые значения как для входных, так и для выходных данных.289> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.290> - Метод `elements()` требует целочисленных счётчиков. Он игнорирует нулевые и отрицательные счётчики.291292> **См. также**293>294> - [Класс Bag](https://python-all.ru/3.6/library/collections.html) в Smalltalk.295> - Статья в Википедии о [мультимножествах](https://python-all.ru/3.6/library/collections.html).296> - [Мультимножества в C++](https://python-all.ru/3.6/library/collections.html): учебное пособие с примерами.297> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.298> - Для перечисления всех различных мультимножеств заданного размера над заданным набором элементов см. [`itertools.combinations_with_replacement()`](https://python-all.ru/3.6/library/itertools.html#itertools.combinations_with_replacement):299>300>   > map(Counter, combinations\_with\_replacement(‘ABC’, 2)) –\> AA AB AC BB BC CC301302## 8.3.3. [`deque`](https://python-all.ru/3.6/library/collections.html#collections.deque) объекты303304#### `class collections.deque([iterable[, maxlen]])`305306Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.6/library/collections.html#collections.deque.append)) данными из *итерируемого объекта*. Если *итерируемый объект* не указан, новый deque пуст.307308Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.309310Хотя объекты [`list`](https://python-all.ru/3.6/library/stdtypes.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и влекут за собой затраты на перемещение памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.311312Если *maxlen* не указан или равен `None`, deques могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque ограниченной длины заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.313314Объекты deque поддерживают следующие методы:315316#### `append(x)`317318Добавляет *x* в правую часть deque.319320#### `appendleft(x)`321322Добавляет *x* в левую часть deque.323324#### `clear()`325326Удаляет все элементы из deque, после чего его длина равна 0.327328#### `copy()`329330Создаёт поверхностную копию deque.331332Новое в версии 3.5.333334#### `count(x)`335336Подсчитывает количество элементов deque, равных *x*.337338Новое в версии 3.2.339340#### `extend(iterable)`341342Расширяет правую часть deque, добавляя элементы из итерируемого объекта.343344#### `extendleft(iterable)`345346Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.347348#### `index(x[, start[, stop]])`349350Возвращает позицию *x* в deque (начиная с индекса *start* и до индекса *stop*). Возвращает первое совпадение или возбуждает [`ValueError`](https://python-all.ru/3.6/library/exceptions.html#ValueError), если не найдено.351352Новое в версии 3.5.353354#### `insert(i, x)`355356Вставляет *x* в deque на позицию *i*.357358Если вставка приведёт к тому, что ограниченный deque превысит *maxlen*, вызывается исключение [`IndexError`](https://python-all.ru/3.6/library/exceptions.html#IndexError).359360Новое в версии 3.5.361362#### `pop()`363364Удаляет и возвращает элемент из правой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/3.6/library/exceptions.html#IndexError).365366#### `popleft()`367368Удаляет и возвращает элемент из левой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/3.6/library/exceptions.html#IndexError).369370#### `remove(value)`371372Удаляет первое вхождение *значения*. Если не найдено, вызывает исключение [`ValueError`](https://python-all.ru/3.6/library/exceptions.html#ValueError).373374#### `reverse()`375376Переворачивает элементы deque на месте и возвращает `None`.377378Новое в версии 3.2.379380#### `rotate(n=1)`381382Поворачивает deque на *n* шагов вправо. Если *n* отрицательное, поворачивает влево.383384Когда deque не пуст, поворот на один шаг вправо эквивалентен `d.appendleft(d.pop())`, а поворот на один шаг влево – `d.append(d.popleft())`.385386Объекты deque также предоставляют один атрибут только для чтения:387388#### `maxlen`389390Максимальный размер дека или `None`, если неограничен.391392Новое в версии 3.1.393394В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.6/reference/expressions.html#in) и обращения по индексу, такие как `d[-1]`. Доступ по индексу выполняется за O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.395396Начиная с версии 3.5, деки поддерживают `__add__()`, `__mul__()` и `__imul__()`.397398Пример:399400```pycon401>>> from collections import deque402>>> d = deque('ghi')                 # создать новый deque с тремя элементами403>>> for elem in d:                   # обход элементов deque404...     print(elem.upper())405G406H407I408409>>> d.append('j')                    # добавить новый элемент справа410>>> d.appendleft('f')                # добавить новый элемент слева411>>> d                                # показать представление deque412deque(['f', 'g', 'h', 'i', 'j'])413414>>> d.pop()                          # вернуть и удалить правый элемент415'j'416>>> d.popleft()                      # вернуть и удалить левый элемент417'f'418>>> list(d)                          # вывести содержимое deque419['g', 'h', 'i']420>>> d[0]                             # посмотреть левый элемент421'g'422>>> d[-1]                            # посмотреть правый элемент423'i'424425>>> list(reversed(d))                # вывести содержимое deque в обратном порядке426['i', 'h', 'g']427>>> 'h' in d                         # поиск в deque428True429>>> d.extend('jkl')                  # добавить несколько элементов за раз430>>> d431deque(['g', 'h', 'i', 'j', 'k', 'l'])432>>> d.rotate(1)                      # поворот вправо433>>> d434deque(['l', 'g', 'h', 'i', 'j', 'k'])435>>> d.rotate(-1)                     # поворот влево436>>> d437deque(['g', 'h', 'i', 'j', 'k', 'l'])438439>>> deque(reversed(d))               # создать новую deque в обратном порядке440deque(['l', 'k', 'j', 'i', 'h', 'g'])441>>> d.clear()                        # очистить deque442>>> d.pop()                          # невозможно извлечь элемент из пустой deque443Traceback (most recent call last):444    File "<pyshell#6>", line 1, in -toplevel-445        d.pop()446IndexError: pop from an empty deque447448>>> d.extendleft('abc')              # extendleft() меняет порядок ввода на обратный449>>> d450deque(['c', 'b', 'a'])451```452453### 8.3.3.1. [`deque`](https://python-all.ru/3.6/library/collections.html#collections.deque) Рецепты454455В этом разделе рассматриваются различные подходы к работе с деками.456457Деки с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:458459```python460def tail(filename, n=10):461    'Return the last n lines of a file'462    with open(filename) as f:463        return deque(f, n)464```465466Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:467468```python469def moving_average(iterable, n=3):470    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0471    # http://en.wikipedia.org/wiki/Moving_average472    it = iter(iterable)473    d = deque(itertools.islice(it, n-1))474    d.appendleft(0)475    s = sum(d)476    for elem in it:477        s += elem - d.popleft()478        d.append(elem)479        yield s / n480```481482Метод `rotate()` позволяет реализовать [`deque`](https://python-all.ru/3.6/library/collections.html#collections.deque) срезы и удаление. Например, чистая реализация `del d[n]` на Python использует метод `rotate()` для позиционирования элементов, которые нужно извлечь:483484```python485def delete_nth(d, n):486    d.rotate(-n)487    d.popleft()488    d.rotate(n)489```490491To implement [`deque`](https://python-all.ru/3.6/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`.492493## 8.3.4. [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) объекты494495#### `class collections.defaultdict([default_factory[, ...]])`496497Возвращает новый объект, похожий на словарь. [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict), и здесь не описывается.498499Первый аргумент задает начальное значение для атрибута [`default_factory`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.default_factory); по умолчанию он равен `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict), включая именованные аргументы.500501[`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) объекты поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict):502503#### `__missing__(key)`504505Если атрибут [`default_factory`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.default_factory) равен `None`, возникает исключение [`KeyError`](https://python-all.ru/3.6/library/exceptions.html#KeyError) с аргументом *key*.506507Если [`default_factory`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов для предоставления значения по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.508509Если вызов [`default_factory`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.default_factory) вызывает исключение, это исключение распространяется без изменений.510511Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.6/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict), когда запрошенный ключ не найден; все, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.6/reference/datamodel.html#object.__getitem__).512513Обратите внимание, что [`__missing__()`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.__missing__) *не* вызывается ни для каких операций, кроме [`__getitem__()`](https://python-all.ru/3.6/reference/datamodel.html#object.__getitem__). Это означает, что `get()` будет, как обычные словари, возвращать `None` по умолчанию, а не использовать [`default_factory`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.default_factory).514515[`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) объекты поддерживают следующую переменную экземпляра:516517#### `default_factory`518519Этот атрибут используется методом [`__missing__()`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он передан, или `None`, если не передан.520521### 8.3.4.1. [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) Примеры522523Используя [`list`](https://python-all.ru/3.6/library/stdtypes.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:524525```python526>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]527>>> d = defaultdict(list)528>>> for k, v in s:529...     d[k].append(v)530...531>>> sorted(d.items())532[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]533```534535Когда ключ встречается впервые, его еще нет в отображении; поэтому запись автоматически создается с помощью функции `default_factory`, которая возвращает пустой [`list`](https://python-all.ru/3.6/library/stdtypes.html#list). Затем операция `list.append()` присоединяет значение к новому списку. Когда ключи встречаются снова, поиск выполняется обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет еще одно значение в список. Этот метод проще и быстрее, чем эквивалентный метод с использованием [`dict.setdefault()`](https://python-all.ru/3.6/library/stdtypes.html#dict.setdefault):536537```python538>>> d = {}539>>> for k, v in s:540...     d.setdefault(k, []).append(v)541...542>>> sorted(d.items())543[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]544```545546Установка `default_factory` в [`int`](https://python-all.ru/3.6/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) удобным для подсчёта (как bag или мультимножество в других языках):547548```python549>>> s = 'mississippi'550>>> d = defaultdict(int)551>>> for k in s:552...     d[k] += 1553...554>>> sorted(d.items())555[('i', 4), ('m', 1), ('p', 2), ('s', 4)]556```557558Когда буква встречается впервые, в отображении она отсутствует, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.6/library/functions.html#int) для получения нулевого значения по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.559560Функция [`int()`](https://python-all.ru/3.6/library/functions.html#int), всегда возвращающая ноль, – это всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):561562```python563>>> def constant_factory(value):564...     return lambda: value565>>> d = defaultdict(constant_factory('<missing>'))566>>> d.update(name='John', action='ran')567>>> '%(name)s %(action)s to %(object)s' % d568'John ran to <missing>'569```570571Установка `default_factory` в [`set`](https://python-all.ru/3.6/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.6/library/collections.html#collections.defaultdict) удобным для построения словаря множеств:572573```python574>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]575>>> d = defaultdict(set)576>>> for k, v in s:577...     d[k].add(v)578...579>>> sorted(d.items())580[('blue', {2, 4}), ('red', {1, 3})]581```582583## 8.3.5. [`namedtuple()`](https://python-all.ru/3.6/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями584585Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.586587#### `collections.namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)`588589Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежам, поля которых доступны через атрибуты, а также поддерживают индексацию и итерацию. Экземпляры подкласса также имеют полезную docstring (с именем типа и именами полей) и полезный метод [`__repr__()`](https://python-all.ru/3.6/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.590591Параметр *field\_names* представляет собой последовательность строк, например `['x', 'y']`. В качестве альтернативы *field\_names* может быть единой строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`.592593В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и символов подчёркивания, но не начинаются с цифры или подчёркивания и не могут быть [`keyword`](https://python-all.ru/3.6/library/keyword.html#module-keyword), например *class*, *for*, *return*, *global*, *pass*, или *raise*.594595Если *rename* равен true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, устраняя ключевое слово `def` и дублирующееся имя поля `abc`.596597Если *verbose* равно true, определение класса выводится после его создания. Эта опция устарела; вместо этого проще вывести атрибут `_source`.598599Если определён *module*, атрибут `__module__` именованного кортежа устанавливается в это значение.600601Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.602603Изменено в версии 3.1: Добавлена поддержка *rename*.604605Изменено в версии 3.6: Параметры *verbose* и *rename* стали [только именованными аргументами](https://python-all.ru/3.6/glossary.html#keyword-only-parameter).606607Изменено в версии 3.6: Добавлен параметр *module*.608609```pycon610>>> # Базовый пример611>>> Point = namedtuple('Point', ['x', 'y'])612>>> p = Point(11, y=22)     # создать экземпляр с позиционными или именованными аргументами613>>> p[0] + p[1]             # доступен по индексу, как обычный кортеж (11, 22)61433615>>> x, y = p                # распаковывается как обычный кортеж616>>> x, y617(11, 22)618>>> p.x + p.y               # поля также доступны по имени61933620>>> p                       # читаемое __repr__ в стиле name=value621Point(x=11, y=22)622```623624Именованные кортежи особенно полезны для присваивания имён полей кортежам результатов, возвращаемых модулями [`csv`](https://python-all.ru/3.6/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.6/library/sqlite3.html#module-sqlite3):625626```python627EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')628629import csv630for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):631    print(emp.name, emp.title)632633import sqlite3634conn = sqlite3.connect('/companydata')635cursor = conn.cursor()636cursor.execute('SELECT name, age, title, department, paygrade FROM employees')637for emp in map(EmployeeRecord._make, cursor.fetchall()):638    print(emp.name, emp.title)639```640641В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и два атрибута. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.642643#### `classmethod somenamedtuple._make(iterable)`644645Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.646647```pycon648>>> t = [11, 22]649>>> Point._make(t)650Point(x=11, y=22)651```652653#### `somenamedtuple._asdict()`654655Возвращает новый [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict), который отображает имена полей в соответствующие значения:656657```pycon658>>> p = Point(x=11, y=22)659>>> p._asdict()660OrderedDict([('x', 11), ('y', 22)])661```662663Изменено в версии 3.1: Возвращает [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict).664665#### `somenamedtuple._replace(**kwargs)`666667Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:668669```python670>>> p = Point(x=11, y=22)671>>> p._replace(x=33)672Point(x=33, y=22)673674>>> for partnum, record in inventory.items():675...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())676```677678#### `somenamedtuple._source`679680Строка с исходным кодом на чистом Python, используемым для создания класса именованного кортежа. Этот исходный код делает именованный кортеж самодокументируемым. Его можно вывести, выполнить с помощью [`exec()`](https://python-all.ru/3.6/library/functions.html#exec) или сохранить в файл и импортировать.681682Новое в версии 3.3.683684#### `somenamedtuple._fields`685686Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.687688```pycon689>>> p._fields            # просмотреть имена полей690('x', 'y')691692>>> Color = namedtuple('Color', 'red green blue')693>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)694>>> Pixel(11, 22, 128, 255, 0)695Pixel(x=11, y=22, red=128, green=255, blue=0)696```697698Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.6/library/functions.html#getattr) :699700```python701>>> getattr(p, 'x')70211703```704705Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [Распаковка списков аргументов](https://python-all.ru/3.6/tutorial/controlflow.html#tut-unpacking-arguments)):706707```python708>>> d = {'x': 11, 'y': 22}709>>> Point(**d)710Point(x=11, y=22)711```712713Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:714715```pycon716>>> class Point(namedtuple('Point', ['x', 'y'])):717...     __slots__ = ()718...     @property719...     def hypot(self):720...         return (self.x ** 2 + self.y ** 2) ** 0.5721...     def __str__(self):722...         return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)723724>>> for p in Point(3, 4), Point(14, 5/7):725...     print(p)726Point: x= 3.000  y= 4.000  hypot= 5.000727Point: x=14.000  y= 0.714  hypot=14.018728```729730Подкласс, показанный выше, устанавливает `__slots__` в пустой кортеж. Это помогает снизить требования к памяти, предотвращая создание словарей экземпляров.731732Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа из атрибута `_fields`:733734```python735>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))736```737738Докстринги можно настроить, напрямую присваивая значения полям `__doc__` :739740```python741>>> Book = namedtuple('Book', ['id', 'title', 'authors'])742>>> Book.__doc__ += ': Hardcover book in active collection'743>>> Book.id.__doc__ = '13-digit ISBN'744>>> Book.title.__doc__ = 'Title of first printing'745>>> Book.authors.__doc__ = 'List of authors sorted by last name'746```747748Изменено в версии 3.5: Докстринги свойств стали доступны для записи.749750Значения по умолчанию могут быть реализованы с помощью `_replace()` для настройки экземпляра-прототипа:751752```python753>>> Account = namedtuple('Account', 'owner balance transaction_count')754>>> default_account = Account('<owner name>', 0.0, 0)755>>> johns_account = default_account._replace(owner='John')756>>> janes_account = default_account._replace(owner='Jane')757```758759> **См. также**760>761> - [Рецепт абстрактного базового класса именованного кортежа с примесью метакласса](https://python-all.ru/3.6/library/collections.html) от Яна Калишевского. Кроме предоставления [абстрактного базового класса](https://python-all.ru/3.6/glossary.html#term-abstract-base-class) для именованных кортежей, он также поддерживает альтернативный конструктор на основе [метакласса](https://python-all.ru/3.6/glossary.html#term-metaclass), что удобно для случаев, когда именованные кортежи наследуются.762> - Смотрите [`types.SimpleNamespace()`](https://python-all.ru/3.6/library/types.html#types.SimpleNamespace) для изменяемого пространства имён на основе словаря вместо кортежа.763> - Смотрите [`typing.NamedTuple()`](https://python-all.ru/3.6/library/typing.html#typing.NamedTuple) о способе добавления аннотаций типов для именованных кортежей.764765## 8.3.6. [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) объекты766767Упорядоченные словари работают как обычные словари, но запоминают порядок, в котором были добавлены элементы. При итерации по упорядоченному словарю элементы возвращаются в том порядке, в котором их ключи были впервые добавлены.768769#### `class collections.OrderedDict([items])`770771Возвращает экземпляр подкласса dict, поддерживающего обычные методы [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict). *OrderedDict* – это словарь, который запоминает порядок, в котором ключи были впервые вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки не изменяется. Удаление записи и повторная вставка переместит её в конец.772773Новое в версии 3.1.774775#### `popitem(last=True)`776777Метод [`popitem()`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (key, value). Пары возвращаются в порядке LIFO, если *last* истинно, или в порядке FIFO, если ложно.778779#### `move_to_end(key, last=True)`780781Перемещает существующий *ключ* в начало или конец упорядоченного словаря. Элемент перемещается в конец, если *last* истинно (по умолчанию), или в начало, если *last* ложно. Вызывает [`KeyError`](https://python-all.ru/3.6/library/exceptions.html#KeyError), если *ключ* не существует:782783```python784>>> d = OrderedDict.fromkeys('abcde')785>>> d.move_to_end('b')786>>> ''.join(d.keys())787'acdeb'788>>> d.move_to_end('b', last=False)789>>> ''.join(d.keys())790'bacde'791```792793Новое в версии 3.2.794795Помимо обычных методов отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.6/library/functions.html#reversed).796797Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) чувствительны к порядку и реализованы как `list(od1.items())==list(od2.items())`. Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/3.6/library/collections.abc.html#collections.abc.Mapping) нечувствительны к порядку, как обычные словари. Это позволяет подставлять объекты [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) в любом месте, где используется обычный словарь.798799Изменено в версии 3.5: Представления [представления](https://python-all.ru/3.6/glossary.html#term-dictionary-view) элементов, ключей и значений объекта [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) теперь поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.6/library/functions.html#reversed).800801Изменено в версии 3.6: С принятием [**PEP 468**](https://python-all.ru/3.6/library/collections.html) порядок сохраняется для именованных аргументов, передаваемых конструктору [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) и его методу `update()` .802803### 8.3.6.1. [`OrderedDict`](https://python-all.ru/3.6/library/collections.html#collections.OrderedDict) Примеры и рецепты804805Поскольку упорядоченный словарь запоминает порядок вставки, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:806807```python808>>> # обычный неотсортированный словарь809>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}810811>>> # словарь, отсортированный по ключу812>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))813OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])814815>>> # словарь, отсортированный по значению816>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))817OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])818819>>> # словарь, отсортированный по длине строки ключа820>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))821OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])822```823824Новые отсортированные словари сохраняют порядок сортировки при удалении записей. Но при добавлении новых ключей они добавляются в конец, и сортировка не сохраняется.825826Также несложно создать вариант упорядоченного словаря, который запоминает порядок, в котором ключи были *в последний раз* вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки меняется и перемещается в конец:827828```python829class LastUpdatedOrderedDict(OrderedDict):830    'Store items in the order the keys were last added'831832    def __setitem__(self, key, value):833        if key in self:834            del self[key]835        OrderedDict.__setitem__(self, key, value)836```837838Упорядоченный словарь можно комбинировать с классом [`Counter`](https://python-all.ru/3.6/library/collections.html#collections.Counter), чтобы счётчик запоминал порядок, в котором элементы встречаются впервые:839840```python841class OrderedCounter(Counter, OrderedDict):842    'Counter that remembers the order elements are first encountered'843844    def __repr__(self):845        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))846847    def __reduce__(self):848        return self.__class__, (OrderedDict(self),)849```850851## 8.3.7. [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict) объекты852853Класс [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов-словарей. Необходимость в этом классе отчасти утрачена из-за возможности наследовать напрямую от [`dict`](https://python-all.ru/3.6/library/stdtypes.html#dict); однако с ним может быть проще работать, поскольку базовый словарь доступен как атрибут.854855#### `class collections.UserDict([initialdata])`856857Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, доступном через атрибут [`data`](https://python-all.ru/3.6/library/collections.html#collections.UserDict.data) экземпляров [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict). Если указан параметр *initialdata*, то [`data`](https://python-all.ru/3.6/library/collections.html#collections.UserDict.data) инициализируется его содержимым; обратите внимание, что ссылка на *initialdata* не сохраняется, что позволяет использовать её для других целей.858859В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict) предоставляют следующий атрибут:860861#### `data`862863Реальный словарь, используемый для хранения содержимого класса [`UserDict`](https://python-all.ru/3.6/library/collections.html#collections.UserDict) .864865## 8.3.8. [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList) объекты866867Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.868869Необходимость в этом классе отчасти утрачена из-за возможности наследовать напрямую от [`list`](https://python-all.ru/3.6/library/stdtypes.html#list); однако с этим классом может быть проще работать, поскольку базовый список доступен как атрибут.870871#### `class collections.UserList([list])`872873Класс, который имитирует список. Содержимое экземпляра хранится в обычном списке, доступном через атрибут [`data`](https://python-all.ru/3.6/library/collections.html#collections.UserList.data) экземпляров [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList). Содержимое экземпляра изначально устанавливается как копия *list*, по умолчанию – пустой список `[]`. *list* может быть любым итерируемым объектом, например настоящим списком Python или объектом [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList).874875В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList) предоставляют следующий атрибут:876877#### `data`878879Настоящий объект [`list`](https://python-all.ru/3.6/library/stdtypes.html#list), используемый для хранения содержимого класса [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList).880881**Требования к подклассам:** Ожидается, что подклассы [`UserList`](https://python-all.ru/3.6/library/collections.html#collections.UserList) предоставляют конструктор, который можно вызывать без аргументов или с одним аргументом. Операции со списками, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром – объектом-последовательностью, используемым как источник данных.882883Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.884885## 8.3.9. [`UserString`](https://python-all.ru/3.6/library/collections.html#collections.UserString) объекты886887Класс [`UserString`](https://python-all.ru/3.6/library/collections.html#collections.UserString) выступает в качестве обёртки для строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создания подклассов непосредственно от [`str`](https://python-all.ru/3.6/library/stdtypes.html#str); однако с этим классом может быть проще работать, так как базовая строка доступна в виде атрибута.888889#### `class collections.UserString([sequence])`890891Класс, который имитирует строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, доступном через атрибут `data` экземпляров [`UserString`](https://python-all.ru/3.6/library/collections.html#collections.UserString). Изначально содержимое экземпляра устанавливается в копию *sequence*. *sequence* может быть экземпляром [`bytes`](https://python-all.ru/3.6/library/stdtypes.html#bytes), [`str`](https://python-all.ru/3.6/library/stdtypes.html#str), [`UserString`](https://python-all.ru/3.6/library/collections.html#collections.UserString) (или подкласса) или произвольной последовательностью, которую можно преобразовать в строку с помощью встроенной функции [`str()`](https://python-all.ru/3.6/library/stdtypes.html#str).892893Изменено в версии 3.5: Новые методы `__getnewargs__`, `__rmod__`, `casefold`, `format_map`, `isprintable` и `maketrans`.894