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

collections.md

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

1> **Источник:** https://python-all.ru/3.4/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.4/library/collections.html#module-collections) – Типы контейнеров89**Исходный код:** [Lib/collections/\_\_init\_\_.py](https://python-all.ru/src/3.4/Lib/collections/__init__.py)1011---1213Этот модуль реализует специализированные типы контейнеров, которые служат альтернативой встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.4/library/stdtypes.html#list), [`set`](https://python-all.ru/3.4/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.4/library/stdtypes.html#tuple).1415| [`namedtuple()`](https://python-all.ru/3.4/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями |16| --- | --- |17| [`deque`](https://python-all.ru/3.4/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов |18| [`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap) | класс, подобный словарю, для создания единого представления нескольких отображений |19| [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов |20| [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей |21| [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений |22| [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict) | обёртка вокруг словарей для упрощения создания подклассов dict |23| [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList) | обёртка вокруг списков для упрощения создания подклассов list |24| [`UserString`](https://python-all.ru/3.4/library/collections.html#collections.UserString) | обёртка вокруг строк для упрощения создания подклассов str |2526Изменено в версии 3.3: Абстрактные базовые классы коллекций [*Collections Abstract Base Classes*](https://python-all.ru/3.4/library/collections.abc.html#collections-abstract-base-classes) перенесены в модуль [`collections.abc`](https://python-all.ru/3.4/library/collections.abc.html#module-collections.abc). Для обратной совместимости они по-прежнему доступны и в этом модуле.2728## 8.3.1. [`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap) объекты2930Новое в версии 3.3.3132Класс [`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap) используется для быстрого объединения нескольких отображений в единое целое. Он часто работает намного быстрее, чем создание нового словаря и выполнение множества вызовов [`update()`](https://python-all.ru/3.4/library/stdtypes.html#dict.update).3334Класс можно использовать для имитации вложенных областей видимости; он полезен в шаблонизаторах.3536#### `class collections.ChainMap(*maps)`3738[`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap) группирует несколько словарей или других отображений в единое изменяемое представление. Если параметр *maps* не указан, используется один пустой словарь, чтобы новая цепочка всегда содержала хотя бы одно отображение.3940Базовые отображения хранятся в списке. Этот список является общедоступным и может быть получен или изменён с помощью атрибута *maps*. Других состояний нет.4142При поиске последовательно просматриваются базовые отображения, пока не будет найден ключ. В отличие от этого, записи, обновления и удаления работают только с первым отображением.4344[`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap) включает базовые отображения по ссылке. Таким образом, если одно из базовых отображений обновляется, эти изменения будут отражены в [`ChainMap`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap).4546Поддерживаются все обычные методы словаря. Кроме того, имеется атрибут *maps*, метод для создания новых подконтекстов и свойство для доступа ко всем отображениям, кроме первого:4748#### `maps`4950Обновляемый пользователем список отображений. Список упорядочен от первого просматриваемого к последнему. Это единственное сохраняемое состояние, и его можно изменять, чтобы менять порядок поиска отображений. Список всегда должен содержать хотя бы одно отображение.5152#### `new_child(m=None)`5354Возвращает новый [`ChainMap`](https://python-all.ru/3.4/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.4/library/collections.html#collections.ChainMap), содержащий все отображения текущего экземпляра, кроме первого. Это полезно для пропуска первого отображения при поиске. Варианты использования аналогичны ключевому слову [`nonlocal`](https://python-all.ru/3.4/reference/simple_stmts.html#nonlocal), используемому в [*вложенных областях видимости*](https://python-all.ru/3.4/glossary.html#term-nested-scope). Также случаи использования перекликаются со встроенной функцией [`super()`](https://python-all.ru/3.4/library/functions.html#super). Ссылка на `d.parents` эквивалентна: `ChainMap(*d.maps[1:])`.6162> **См. также**63>64> - Класс [MultiContext](https://python-all.ru/3.4/library/collections.html) в пакете Enthought [CodeTools](https://python-all.ru/3.4/library/collections.html) имеет опции для поддержки записи в любое отображение в цепочке.65> - Класс [Context](https://python-all.ru/3.4/library/collections.html) из Django для шаблонов представляет собой цепочку отображений только для чтения. Он также поддерживает добавление и удаление контекстов, аналогично методу [`new_child()`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap.new_child) и свойству [`parents()`](https://python-all.ru/3.4/library/collections.html#collections.ChainMap.parents).66> - Рецепт [Nested Contexts](https://python-all.ru/3.4/library/collections.html) содержит опции для управления тем, применяются ли записи и другие изменения только к первому отображению или к любому отображению в цепочке.67> - [Сильно упрощённая версия Chainmap только для чтения](https://python-all.ru/3.4/library/collections.html).6869### 8.3.1.1. [`ChainMap`](https://python-all.ru/3.4/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.4/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.4/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']            # удалить существующий ключ на один уровень ниже142DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})143```144145## 8.3.2. [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) объекты146147Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:148149```python150>>> # Подсчитать вхождения слов в списке151>>> cnt = Counter()152>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:153...     cnt[word] += 1154>>> cnt155Counter({'blue': 3, 'red': 2, 'green': 1})156157>>> # Найти десять самых распространённых слов в «Гамлете»158>>> import re159>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())160>>> Counter(words).most_common(10)161[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),162 ('you', 554),  ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]163```164165#### `class collections.Counter([iterable-or-mapping])`166167[`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) – это подкласс [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict) для подсчёта хешируемых объектов. Это неупорядоченная коллекция, в которой элементы хранятся как ключи словаря, а их количества – как значения словаря. Количества могут быть любыми целыми числами, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) аналогичен мультимножествам (bags или multisets) в других языках.168169Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):170171```python172>>> c = Counter()                           # новый пустой счётчик173>>> c = Counter('gallahad')                 # новый счётчик из итерируемого объекта174>>> c = Counter({'red': 4, 'blue': 2})      # новый счётчик из отображения175>>> c = Counter(cats=4, dogs=8)             # новый счётчик из именованных аргументов176```177178Объекты Counter имеют интерфейс словаря, за исключением того, что при отсутствии элемента они возвращают нулевой счёт вместо возбуждения [`KeyError`](https://python-all.ru/3.4/library/exceptions.html#KeyError):179180```python181>>> c = Counter(['eggs', 'ham'])182>>> c['bacon']                              # счёт отсутствующего элемента равен нулю1830184```185186Установка счёта в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:187188```python189>>> c['sausage'] = 0                        # запись счётчика с нулевым значением190>>> del c['sausage']                        # del действительно удаляет запись191```192193Новое в версии 3.1.194195Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:196197#### `elements()`198199Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его счёте. Элементы возвращаются в произвольном порядке. Если счёт элемента меньше единицы, [`elements()`](https://python-all.ru/3.4/library/collections.html#collections.Counter.elements) игнорирует его.200201```python202>>> c = Counter(a=4, b=2, c=0, d=-2)203>>> list(c.elements())204['a', 'a', 'a', 'a', 'b', 'b']205```206207#### `most_common([n])`208209Возвращает список из *n* наиболее часто встречающихся элементов и их счётов, от самого частого к самому редкому. Если *n* опущен или равен `None`, [`most_common()`](https://python-all.ru/3.4/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковым счётом упорядочиваются произвольно:210211```python212>>> Counter('abracadabra').most_common(3)213[('a', 5), ('r', 2), ('b', 2)]214```215216#### `subtract([iterable-or-mapping])`217218Элементы вычитаются из *iterable* или из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.4/library/stdtypes.html#dict.update), но вычитает счёты вместо их замены. И входные, и выходные значения могут быть нулевыми или отрицательными.219220```python221>>> c = Counter(a=4, b=2, c=0, d=-2)222>>> d = Counter(a=1, b=2, c=3, d=4)223>>> c.subtract(d)224>>> c225Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})226```227228Новое в версии 3.2.229230Для объектов [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) доступны обычные методы словаря, за исключением двух, которые работают иначе для счётчиков.231232#### `fromkeys(iterable)`233234Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter).235236#### `update([iterable-or-mapping])`237238Элементы подсчитываются из *iterable* или добавляются из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.4/library/stdtypes.html#dict.update), но добавляет счёты вместо их замены. Кроме того, *iterable* должен быть последовательностью элементов, а не последовательностью пар `(key, value)`.239240Распространённые приёмы работы с объектами [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter):241242```python243sum(c.values())                 # сумма всех значений244c.clear()                       # сбросить все значения245list(c)                         # список уникальных элементов246set(c)                          # преобразовать в множество247dict(c)                         # преобразовать в обычный словарь248c.items()                       # преобразовать в список пар (elem, cnt)249Counter(dict(list_of_pairs))    # создать из списка пар (элемент, кол-во)250c.most_common()[:-n-1:-1]       # n наименее частых элементов251+c                              # удалить нулевые и отрицательные значения252```253254Для объединения объектов [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) в мультимножества (счётчики, в которых счёты больше нуля) предусмотрено несколько математических операций. Сложение и вычитание объединяют счётчики путём сложения или вычитания счётов соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих счётов. Каждая операция может принимать входные данные со знаковыми счётами, но на выходе будут исключены результаты со счётом ноль или меньше.255256```python257>>> c = Counter(a=3, b=1)258>>> d = Counter(a=1, b=2)259>>> c + d                       # сложение двух счётчиков: c[x] + d[x]260Counter({'a': 4, 'b': 3})261>>> c - d                       # вычитание (остаются только положительные значения)262Counter({'a': 2})263>>> c & d                       # пересечение: min(c[x], d[x])264Counter({'a': 1, 'b': 1})265>>> c | d                       # объединение: max(c[x], d[x])266Counter({'a': 3, 'b': 2})267```268269Унарное сложение и вычитание – это сокращения для добавления пустого счётчика или вычитания из пустого счётчика.270271```python272>>> c = Counter(a=2, b=-4)273>>> +c274Counter({'a': 2})275>>> -c276Counter({'b': 4})277```278279Новое в версии 3.3: Добавлена поддержка унарного плюса, унарного минуса и операций над мультимножествами на месте.280281> **Примечание**282>283> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.284>285> - Сам класс [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения предназначены для чисел, представляющих счёты, но в поле значения *можно* хранить что угодно.286> - Метод `most_common()` требует только, чтобы значения были упорядочиваемыми.287> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа подойдут, а отрицательные значения поддерживаются. То же самое верно для `update()` и `subtract()`, которые допускают отрицательные и нулевые значения как на входе, так и на выходе.288> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.289> - Метод `elements()` требует целочисленных счётов. Он игнорирует нулевые и отрицательные счёты.290291> **См. также**292>293> - [Класс Bag](https://python-all.ru/3.4/library/collections.html) в Smalltalk.294> - Статья в Википедии о [мультимножествах](https://python-all.ru/3.4/library/collections.html).295> - [Мультимножества в C++](https://python-all.ru/3.4/library/collections.html): учебное пособие с примерами.296> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.297> - Чтобы перечислить все различные мультимножества заданного размера из заданного набора элементов, см. [`itertools.combinations_with_replacement()`](https://python-all.ru/3.4/library/itertools.html#itertools.combinations_with_replacement).298>299>   > map(Counter, combinations\_with\_replacement(‘ABC’, 2)) –\> AA AB AC BB BC CC300301## 8.3.3. [`deque`](https://python-all.ru/3.4/library/collections.html#collections.deque) объекты302303#### `class collections.deque([iterable[, maxlen]])`304305Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.4/library/collections.html#collections.deque.append)) данными из *iterable*. Если *iterable* не указан, новый deque пуст.306307Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.308309Хотя объекты [`list`](https://python-all.ru/3.4/library/stdtypes.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и несут затраты памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.310311Если *maxlen* не указан или равен *None*, deque могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque с ограниченной длиной заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.312313Объекты deque поддерживают следующие методы:314315#### `append(x)`316317Добавляет *x* в правую часть deque.318319#### `appendleft(x)`320321Добавляет *x* в левую часть deque.322323#### `clear()`324325Удаляет все элементы из deque, после чего его длина равна 0.326327#### `count(x)`328329Подсчитывает количество элементов deque, равных *x*.330331Новое в версии 3.2.332333#### `extend(iterable)`334335Расширяет правую часть deque, добавляя элементы из итерируемого объекта.336337#### `extendleft(iterable)`338339Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.340341#### `pop()`342343Удаляет и возвращает элемент с правой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError).344345#### `popleft()`346347Удаляет и возвращает элемент с левой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.4/library/exceptions.html#IndexError).348349#### `remove(value)`350351Удаляет первое вхождение *value*. Если не найдено, возбуждает [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError).352353#### `reverse()`354355Переворачивает элементы deque по месту и затем возвращает `None`.356357Новое в версии 3.2.358359#### `rotate(n)`360361Поворачивает deque на *n* шагов вправо. Если *n* отрицательно, поворачивает влево. Поворот на один шаг вправо эквивалентен: `d.appendleft(d.pop())`.362363Объекты deque также предоставляют один атрибут только для чтения:364365#### `maxlen`366367Максимальный размер deque или *None*, если неограничен.368369Новое в версии 3.1.370371В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.4/reference/expressions.html#in) и доступ по индексу, например `d[-1]`. Индексированный доступ занимает O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.372373Пример:374375```python376>>> from collections import deque377>>> d = deque('ghi')                 # создать новый deque с тремя элементами378>>> for elem in d:                   # обход элементов deque379...     print(elem.upper())380G381H382I383384>>> d.append('j')                    # добавить новый элемент справа385>>> d.appendleft('f')                # добавить новый элемент слева386>>> d                                # показать представление deque387deque(['f', 'g', 'h', 'i', 'j'])388389>>> d.pop()                          # вернуть и удалить правый элемент390'j'391>>> d.popleft()                      # вернуть и удалить левый элемент392'f'393>>> list(d)                          # вывести содержимое deque394['g', 'h', 'i']395>>> d[0]                             # посмотреть левый элемент396'g'397>>> d[-1]                            # посмотреть правый элемент398'i'399400>>> list(reversed(d))                # вывести содержимое deque в обратном порядке401['i', 'h', 'g']402>>> 'h' in d                         # поиск в deque403True404>>> d.extend('jkl')                  # добавить несколько элементов за раз405>>> d406deque(['g', 'h', 'i', 'j', 'k', 'l'])407>>> d.rotate(1)                      # поворот вправо408>>> d409deque(['l', 'g', 'h', 'i', 'j', 'k'])410>>> d.rotate(-1)                     # поворот влево411>>> d412deque(['g', 'h', 'i', 'j', 'k', 'l'])413414>>> deque(reversed(d))               # создать новую deque в обратном порядке415deque(['l', 'k', 'j', 'i', 'h', 'g'])416>>> d.clear()                        # очистить deque417>>> d.pop()                          # невозможно извлечь элемент из пустой deque418Traceback (most recent call last):419    File "<pyshell#6>", line 1, in -toplevel-420        d.pop()421IndexError: pop from an empty deque422423>>> d.extendleft('abc')              # extendleft() меняет порядок ввода на обратный424>>> d425deque(['c', 'b', 'a'])426```427428### 8.3.3.1. [`deque`](https://python-all.ru/3.4/library/collections.html#collections.deque) Рецепты429430В этом разделе рассматриваются различные подходы к работе с деками.431432Двусторонние очереди с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:433434```python435def tail(filename, n=10):436    'Return the last n lines of a file'437    with open(filename) as f:438        return deque(f, n)439```440441Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:442443```python444def moving_average(iterable, n=3):445    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0446    # http://en.wikipedia.org/wiki/Moving_average447    it = iter(iterable)448    d = deque(itertools.islice(it, n-1))449    d.appendleft(0)450    s = sum(d)451    for elem in it:452        s += elem - d.popleft()453        d.append(elem)454        yield s / n455```456457Метод `rotate()` предоставляет способ реализовать срезы и удаление для [`deque`](https://python-all.ru/3.4/library/collections.html#collections.deque). Например, чистая реализация Python для `del d[n]` опирается на метод `rotate()` для позиционирования элементов, которые нужно извлечь:458459```python460def delete_nth(d, n):461    d.rotate(-n)462    d.popleft()463    d.rotate(n)464```465466Чтобы реализовать срезы для [`deque`](https://python-all.ru/3.4/library/collections.html#collections.deque), используйте аналогичный подход, применяя `rotate()` для перемещения целевого элемента к левой стороне deque. Удалите старые записи с помощью `popleft()`, добавьте новые с помощью `extend()`, а затем обратите вращение. С небольшими вариациями этого подхода легко реализовать стековые манипуляции в стиле Forth, такие как `dup`, `drop`, `swap`, `over`, `pick`, `rot` и `roll`.467468## 8.3.4. [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) объекты469470#### `class collections.defaultdict([default_factory[, ...]])`471472Возвращает новый объект, подобный словарю. [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict), и здесь не документируется.473474Первый аргумент задаёт начальное значение для атрибута [`default_factory`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.default_factory); по умолчанию `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict), включая именованные аргументы.475476Объекты [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict):477478#### `__missing__(key)`479480Если атрибут [`default_factory`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.default_factory) равен `None`, это возбуждает исключение [`KeyError`](https://python-all.ru/3.4/library/exceptions.html#KeyError) с *key* в качестве аргумента.481482Если [`default_factory`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов, чтобы предоставить значение по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.483484Если вызов [`default_factory`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.default_factory) возбуждает исключение, это исключение распространяется без изменений.485486Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict), когда запрошенный ключ не найден; то, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__).487488Обратите внимание, что [`__missing__()`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.__missing__) *не* вызывается для любых операций, кроме [`__getitem__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getitem__). Это означает, что `get()`, как и обычные словари, будет возвращать `None` в качестве значения по умолчанию, а не использовать [`default_factory`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.default_factory).489490Объекты [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) поддерживают следующую переменную экземпляра:491492#### `default_factory`493494Этот атрибут используется методом [`__missing__()`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он присутствует, или `None`, если отсутствует.495496### 8.3.4.1. [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) Примеры497498Используя [`list`](https://python-all.ru/3.4/library/stdtypes.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:499500```python501>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]502>>> d = defaultdict(list)503>>> for k, v in s:504...     d[k].append(v)505...506>>> list(d.items())507[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]508```509510Когда ключ встречается впервые, его ещё нет в отображении; поэтому запись автоматически создаётся с помощью функции `default_factory`, которая возвращает пустой [`list`](https://python-all.ru/3.4/library/stdtypes.html#list). Затем операция `list.append()` добавляет значение в новый список. При повторной встрече ключа поиск происходит обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет ещё одно значение в список. Этот метод проще и быстрее, чем эквивалентный приём с [`dict.setdefault()`](https://python-all.ru/3.4/library/stdtypes.html#dict.setdefault):511512```python513>>> d = {}514>>> for k, v in s:515...     d.setdefault(k, []).append(v)516...517>>> list(d.items())518[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]519```520521Установка `default_factory` в [`int`](https://python-all.ru/3.4/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) полезным для подсчёта (как мешок или мультимножество в других языках):522523```python524>>> s = 'mississippi'525>>> d = defaultdict(int)526>>> for k in s:527...     d[k] += 1528...529>>> list(d.items())530[('i', 4), ('p', 2), ('s', 4), ('m', 1)]531```532533Когда буква встречается впервые, она отсутствует в отображении, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.4/library/functions.html#int), чтобы получить нулевое значение по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.534535Функция [`int()`](https://python-all.ru/3.4/library/functions.html#int), которая всегда возвращает ноль, – всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):536537```python538>>> def constant_factory(value):539...     return lambda: value540>>> d = defaultdict(constant_factory('<missing>'))541>>> d.update(name='John', action='ran')542>>> '%(name)s %(action)s to %(object)s' % d543'John ran to <missing>'544```545546Установка `default_factory` в [`set`](https://python-all.ru/3.4/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.4/library/collections.html#collections.defaultdict) полезным для построения словаря множеств:547548```python549>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]550>>> d = defaultdict(set)551>>> for k, v in s:552...     d[k].add(v)553...554>>> list(d.items())555[('blue', {2, 4}), ('red', {1, 3})]556```557558## 8.3.5. Фабричная функция [`namedtuple()`](https://python-all.ru/3.4/library/collections.html#collections.namedtuple) для кортежей с именованными полями559560Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.561562#### `collections.namedtuple(typename, field_names, verbose=False, rename=False)`563564Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежу, поля которых доступны через обращение к атрибутам, а также индексируемы и итерируемы. Экземпляры подкласса также имеют полезную docstring (с именем типа и полями) и полезный метод [`__repr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.565566Параметр *field\_names* может быть строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`. Как вариант, *field\_names* может быть последовательностью строк, например `['x', 'y']`.567568В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и подчёркиваний, но не начинаются с цифры или подчёркивания и не могут быть [`ключевым словом`](https://python-all.ru/3.4/library/keyword.html#module-keyword), таким как *class*, *for*, *return*, *global*, *pass* или *raise*.569570Если *rename* равно true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, удаляя ключевое слово `def` и дублирующееся имя поля `abc`.571572Если *verbose* равно true, определение класса выводится после его создания. Эта опция устарела; вместо этого проще вывести атрибут `_source`.573574Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.575576Изменено в версии 3.1: Добавлена поддержка *rename*.577578```python579>>> # Базовый пример580>>> Point = namedtuple('Point', ['x', 'y'])581>>> p = Point(11, y=22)     # создать экземпляр с позиционными или именованными аргументами582>>> p[0] + p[1]             # доступен по индексу, как обычный кортеж (11, 22)58333584>>> x, y = p                # распаковывается как обычный кортеж585>>> x, y586(11, 22)587>>> p.x + p.y               # поля также доступны по имени58833589>>> p                       # читаемое __repr__ в стиле name=value590Point(x=11, y=22)591```592593Именованные кортежи особенно полезны для присвоения имён полям кортежам результатов, возвращаемым модулями [`csv`](https://python-all.ru/3.4/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.4/library/sqlite3.html#module-sqlite3):594595```python596EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')597598import csv599for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):600    print(emp.name, emp.title)601602import sqlite3603conn = sqlite3.connect('/companydata')604cursor = conn.cursor()605cursor.execute('SELECT name, age, title, department, paygrade FROM employees')606for emp in map(EmployeeRecord._make, cursor.fetchall()):607    print(emp.name, emp.title)608```609610В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и два атрибута. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.611612#### `classmethod somenamedtuple._make(iterable)`613614Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.615616```python617>>> t = [11, 22]618>>> Point._make(t)619Point(x=11, y=22)620```621622#### `somenamedtuple._asdict()`623624Возвращает новый [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict), который сопоставляет имена полей с соответствующими значениями:625626```python627>>> p = Point(x=11, y=22)628>>> p._asdict()629OrderedDict([('x', 11), ('y', 22)])630```631632Изменено в версии 3.1: Возвращает [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict).633634#### `somenamedtuple._replace(kwargs)`635636Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:637638```python639>>> p = Point(x=11, y=22)640>>> p._replace(x=33)641Point(x=33, y=22)642643>>> for partnum, record in inventory.items():644...     inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())645```646647#### `somenamedtuple._source`648649Строка с исходным кодом на чистом Python, использованным для создания класса именованного кортежа. Исходный код делает именованный кортеж самодокументируемым. Его можно вывести на печать, выполнить с помощью [`exec()`](https://python-all.ru/3.4/library/functions.html#exec) или сохранить в файл и импортировать.650651Новое в версии 3.3.652653#### `somenamedtuple._fields`654655Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.656657```python658>>> p._fields            # просмотреть имена полей659('x', 'y')660661>>> Color = namedtuple('Color', 'red green blue')662>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)663>>> Pixel(11, 22, 128, 255, 0)664Pixel(x=11, y=22, red=128, green=255, blue=0)665```666667Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.4/library/functions.html#getattr):668669```python670>>> getattr(p, 'x')67111672```673674Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [*Распаковка списков аргументов*](https://python-all.ru/3.4/tutorial/controlflow.html#tut-unpacking-arguments)):675676```python677>>> d = {'x': 11, 'y': 22}678>>> Point(**d)679Point(x=11, y=22)680```681682Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:683684```python685>>> class Point(namedtuple('Point', 'x y')):686    __slots__ = ()687    @property688    def hypot(self):689        return (self.x ** 2 + self.y ** 2) ** 0.5690    def __str__(self):691        return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)692```693694```python695>>> for p in Point(3, 4), Point(14, 5/7):696    print(p)697Point: x= 3.000  y= 4.000  hypot= 5.000698Point: x=14.000  y= 0.714  hypot=14.018699```700701Приведённый выше подкласс устанавливает `__slots__` в пустой кортеж. Это помогает снизить потребление памяти, предотвращая создание словарей экземпляров.702703Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа на основе атрибута `_fields`:704705```python706>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))707```708709Значения по умолчанию можно реализовать, используя `_replace()` для настройки экземпляра-прототипа:710711```python712>>> Account = namedtuple('Account', 'owner balance transaction_count')713>>> default_account = Account('<owner name>', 0.0, 0)714>>> johns_account = default_account._replace(owner='John')715>>> janes_account = default_account._replace(owner='Jane')716```717718Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простой [`Enum`](https://python-all.ru/3.4/library/enum.html#enum.Enum):719720```python721>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))722>>> Status.open, Status.pending, Status.closed723(0, 1, 2)724>>> from enum import Enum725>>> class Status(Enum):726...     open, pending, closed = range(3)727```728729> **См. также**730>731> - [Рецепт абстрактного базового класса именованного кортежа с примесью метакласса](https://python-all.ru/3.4/library/collections.html) от Яна Калишевского. Кроме предоставления [*абстрактного базового класса*](https://python-all.ru/3.4/glossary.html#term-abstract-base-class) для именованных кортежей, он также поддерживает альтернативный конструктор на основе [*метакласса*](https://python-all.ru/3.4/glossary.html#term-metaclass), что удобно для случаев, когда именованные кортежи наследуются.732733## 8.3.6. Объекты [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict)734735Упорядоченные словари работают как обычные словари, но запоминают порядок, в котором были добавлены элементы. При итерации по упорядоченному словарю элементы возвращаются в том порядке, в котором их ключи были впервые добавлены.736737#### `class collections.OrderedDict([items])`738739Возвращает экземпляр подкласса dict, поддерживающий обычные методы [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict). *OrderedDict* – это словарь, который запоминает порядок, в котором ключи были вставлены впервые. Если новая запись перезаписывает существующую, исходная позиция вставки остаётся неизменной. Удаление записи и повторная вставка перемещает её в конец.740741Новое в версии 3.1.742743#### `popitem(last=True)`744745Метод [`popitem()`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (ключ, значение). Пары возвращаются в порядке LIFO, если *last* равно true, или в порядке FIFO, если false.746747#### `move_to_end(key, last=True)`748749Перемещает существующий *ключ* на любой конец упорядоченного словаря. Элемент перемещается в правый конец, если *last* равно true (по умолчанию), или в начало, если *last* равно false. Возбуждает [`KeyError`](https://python-all.ru/3.4/library/exceptions.html#KeyError), если *ключ* не существует:750751```python752>>> d = OrderedDict.fromkeys('abcde')753>>> d.move_to_end('b')754>>> ''.join(d.keys())755'acdeb'756>>> d.move_to_end('b', last=False)757>>> ''.join(d.keys())758'bacde'759```760761Новое в версии 3.2.762763В дополнение к обычным методам отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.4/library/functions.html#reversed).764765Проверки на равенство между объектами [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) чувствительны к порядку и реализованы как `list(od1.items())==list(od2.items())`. Проверки на равенство между объектами [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/3.4/library/collections.abc.html#collections.abc.Mapping) не чувствительны к порядку, как обычные словари. Это позволяет объектам [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) использоваться вместо обычного словаря где угодно.766767Конструктор [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) и метод `update()` оба принимают именованные аргументы, но их порядок теряется, поскольку семантика вызова функций Python передаёт именованные аргументы через обычный неупорядоченный словарь.768769### 8.3.6.1. [`OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict) Примеры и рецепты770771Поскольку упорядоченный словарь запоминает порядок вставки, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:772773```python774>>> # обычный неотсортированный словарь775>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}776777>>> # словарь, отсортированный по ключу778>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))779OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])780781>>> # словарь, отсортированный по значению782>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))783OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])784785>>> # словарь, отсортированный по длине строки ключа786>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))787OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])788```789790Новые отсортированные словари сохраняют порядок сортировки при удалении записей. Но при добавлении новых ключей они добавляются в конец, и сортировка не сохраняется.791792Также несложно создать вариант упорядоченного словаря, который запоминает порядок, в котором ключи были *в последний раз* вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки меняется и перемещается в конец:793794```python795class LastUpdatedOrderedDict(OrderedDict):796    'Store items in the order the keys were last added'797798    def __setitem__(self, key, value):799        if key in self:800            del self[key]801        OrderedDict.__setitem__(self, key, value)802```803804Упорядоченный словарь можно комбинировать с классом [`Counter`](https://python-all.ru/3.4/library/collections.html#collections.Counter), чтобы счётчик запоминал порядок, в котором элементы встретились впервые:805806```python807class OrderedCounter(Counter, OrderedDict):808    'Counter that remembers the order elements are first encountered'809810    def __repr__(self):811        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))812813    def __reduce__(self):814        return self.__class__, (OrderedDict(self),)815```816817## 8.3.7. Объекты [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict)818819Класс [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов словаря. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`dict`](https://python-all.ru/3.4/library/stdtypes.html#dict); однако с этим классом может быть проще работать, потому что базовый словарь доступен как атрибут.820821#### `class collections.UserDict([initialdata])`822823Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, который доступен через атрибут [`data`](https://python-all.ru/3.4/library/collections.html#collections.UserDict.data) объектов [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict). Если передан *initialdata*, то [`data`](https://python-all.ru/3.4/library/collections.html#collections.UserDict.data) инициализируется его содержимым; обратите внимание, что ссылка на *initialdata* не сохраняется, что позволяет использовать его для других целей.824825В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict) предоставляют следующий атрибут:826827#### `data`828829Настоящий словарь, используемый для хранения содержимого класса [`UserDict`](https://python-all.ru/3.4/library/collections.html#collections.UserDict).830831## 8.3.8. Объекты [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList)832833Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.834835Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`list`](https://python-all.ru/3.4/library/stdtypes.html#list); однако с этим классом может быть проще работать, потому что базовый список доступен как атрибут.836837#### `class collections.UserList([list])`838839Класс, имитирующий список. Содержимое экземпляра хранится в обычном списке, который доступен через атрибут [`data`](https://python-all.ru/3.4/library/collections.html#collections.UserList.data) объектов [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList). Содержимое экземпляра изначально устанавливается в копию *list*, по умолчанию пустой список `[]`. *list* может быть любым итерируемым объектом, например, настоящим списком Python или объектом [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList).840841В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList) предоставляют следующий атрибут:842843#### `data`844845Настоящий объект [`list`](https://python-all.ru/3.4/library/stdtypes.html#list), используемый для хранения содержимого класса [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList).846847**Требования к созданию подклассов:** Ожидается, что подклассы [`UserList`](https://python-all.ru/3.4/library/collections.html#collections.UserList) предоставляют конструктор, который может быть вызван без аргументов или с одним аргументом. Операции со списком, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром, являющимся объектом последовательности, используемым в качестве источника данных.848849Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.850851## 8.3.9. Объекты [`UserString`](https://python-all.ru/3.4/library/collections.html#collections.UserString)852853Класс [`UserString`](https://python-all.ru/3.4/library/collections.html#collections.UserString) действует как обёртка вокруг строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`str`](https://python-all.ru/3.4/library/stdtypes.html#str); однако с этим классом может быть проще работать, потому что базовая строка доступна как атрибут.854855#### `class collections.UserString([sequence])`856857Класс, имитирующий строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, который доступен через атрибут `data` объектов [`UserString`](https://python-all.ru/3.4/library/collections.html#collections.UserString). Содержимое экземпляра изначально устанавливается в копию *sequence*. *sequence* может быть экземпляром [`bytes`](https://python-all.ru/3.4/library/functions.html#bytes), [`str`](https://python-all.ru/3.4/library/stdtypes.html#str), [`UserString`](https://python-all.ru/3.4/library/collections.html#collections.UserString) (или подклассом) или произвольной последовательностью, которая может быть преобразована в строку с помощью встроенной функции [`str()`](https://python-all.ru/3.4/library/stdtypes.html#str).858