collections.md
1> **Источник:** https://python-all.ru/3.3/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.3/library/collections.html#module-collections) – Типы контейнеров89**Исходный код:** [Lib/collections/\_\_init\_\_.py](https://python-all.ru/src/3.3/Lib/collections/__init__.py)1011---1213Этот модуль реализует специализированные типы контейнеров, которые служат альтернативой встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.3/library/stdtypes.html#list), [`set`](https://python-all.ru/3.3/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.3/library/stdtypes.html#tuple).1415| [`namedtuple()`](https://python-all.ru/3.3/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями |16| --- | --- |17| [`deque`](https://python-all.ru/3.3/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов |18| [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) | класс, подобный словарю, для создания единого представления нескольких отображений |19| [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов |20| [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей |21| [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений |22| [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict) | обёртка вокруг словарей для упрощения создания подклассов dict |23| [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList) | обёртка вокруг списков для упрощения создания подклассов list |24| [`UserString`](https://python-all.ru/3.3/library/collections.html#collections.UserString) | обёртка вокруг строк для упрощения создания подклассов str |2526Изменено в версии 3.3: Абстрактные базовые классы коллекций [*Collections Abstract Base Classes*](https://python-all.ru/3.3/library/collections.abc.html#collections-abstract-base-classes) перенесены в модуль [`collections.abc`](https://python-all.ru/3.3/library/collections.abc.html#module-collections.abc). Для обратной совместимости они по-прежнему доступны и в этом модуле.2728## 8.3.1. [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) объекты2930Новое в версии 3.3.3132Класс [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) используется для быстрого объединения нескольких отображений в единое целое. Он часто работает намного быстрее, чем создание нового словаря и выполнение множества вызовов [`update()`](https://python-all.ru/3.3/library/stdtypes.html#dict.update).3334Класс можно использовать для имитации вложенных областей видимости; он полезен в шаблонизаторах.3536#### `class collections.ChainMap(*maps)`3738[`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) группирует несколько словарей или других отображений в единое изменяемое представление. Если параметр *maps* не указан, используется один пустой словарь, чтобы новая цепочка всегда содержала хотя бы одно отображение.3940Базовые отображения хранятся в списке. Этот список является общедоступным и может быть получен или изменён с помощью атрибута *maps*. Других состояний нет.4142При поиске последовательно просматриваются базовые отображения, пока не будет найден ключ. В отличие от этого, записи, обновления и удаления работают только с первым отображением.4344[`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) включает базовые отображения по ссылке. Таким образом, если одно из базовых отображений обновляется, эти изменения будут отражены в [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap).4546Поддерживаются все обычные методы словаря. Кроме того, имеется атрибут *maps*, метод для создания новых подконтекстов и свойство для доступа ко всем отображениям, кроме первого:4748#### `maps`4950Обновляемый пользователем список отображений. Список упорядочен от первого просматриваемого к последнему. Это единственное сохраняемое состояние, и его можно изменять, чтобы менять порядок поиска отображений. Список всегда должен содержать хотя бы одно отображение.5152#### `new_child()`5354Возвращает новый объект [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap), содержащий новый [`словарь`](https://python-all.ru/3.3/library/stdtypes.html#dict), за которым следуют все отображения из текущего экземпляра. Вызов `d.new_child()` эквивалентен: `ChainMap({}, *d.maps)`. Этот метод используется для создания подконтекстов, которые можно обновлять, не изменяя значения ни в одном из родительских отображений.5556#### `parents`5758Свойство, возвращающее новый [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap), содержащий все отображения текущего экземпляра, кроме первого. Это полезно для пропуска первого отображения при поиске. Варианты использования аналогичны ключевому слову [`nonlocal`](https://python-all.ru/3.3/reference/simple_stmts.html#nonlocal), используемому в [*вложенных областях видимости*](https://python-all.ru/3.3/glossary.html#term-nested-scope). Также случаи использования перекликаются со встроенной функцией [`super()`](https://python-all.ru/3.3/library/functions.html#super). Ссылка на `d.parents` эквивалентна: `ChainMap(*d.maps[1:])`.5960> **См. также**61>62> - Класс [MultiContext](https://python-all.ru/3.3/library/collections.html) в пакете Enthought [CodeTools](https://python-all.ru/3.3/library/collections.html) имеет опции для поддержки записи в любое отображение в цепочке.63> - Класс [Context](https://python-all.ru/3.3/library/collections.html) из Django для шаблонов представляет собой цепочку отображений только для чтения. Он также поддерживает добавление и удаление контекстов, аналогично методу [`new_child()`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap.new_child) и свойству [`parents()`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap.parents).64> - Рецепт [Nested Contexts](https://python-all.ru/3.3/library/collections.html) содержит опции для управления тем, применяются ли записи и другие изменения только к первому отображению или к любому отображению в цепочке.65> - [Сильно упрощённая версия Chainmap только для чтения](https://python-all.ru/3.3/library/collections.html).6667### 8.3.1.1. [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) Примеры и рецепты6869В этом разделе показаны различные подходы к работе с цепочечными отображениями.7071Пример симуляции внутренней цепочки поиска Python:7273```python74import builtins75pylookup = ChainMap(locals(), globals(), vars(builtins))76```7778Пример, когда заданные пользователем аргументы командной строки имеют приоритет над переменными окружения, которые, в свою очередь, имеют приоритет над значениями по умолчанию:7980```python81import os, argparse8283defaults = {'color': 'red', 'user': 'guest'}8485parser = argparse.ArgumentParser()86parser.add_argument('-u', '--user')87parser.add_argument('-c', '--color')88namespace = parser.parse_args()89command_line_args = {k:v for k, v in vars(namespace).items() if v}9091combined = ChainMap(command_line_args, os.environ, defaults)92print(combined['color'])93print(combined['user'])94```9596Примеры использования класса [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) для имитации вложенных контекстов:9798```python99c = ChainMap() # Создать корневой контекст100d = c.new_child() # Создать вложенный дочерний контекст101e = c.new_child() # Дочерний контекст c, независимый от d102e.maps[0] # Словарь текущего контекста – как locals() в Python103e.maps[-1] # Корневой контекст – как globals() в Python104e.parents # Цепочка объемлющих контекстов – как nonlocals в Python105106d['x'] # Получить первый ключ в цепочке контекстов107d['x'] = 1 # Установить значение в текущем контексте108del d['x'] # Удалить из текущего контекста109list(d) # Все вложенные значения110k in d # Проверить все вложенные значения111len(d) # Количество вложенных значений112d.items() # Все вложенные элементы113dict(d) # Развернуть в обычный словарь114```115116Класс [`ChainMap`](https://python-all.ru/3.3/library/collections.html#collections.ChainMap) изменяет (записывает и удаляет) только первое отображение в цепочке, тогда как поиск выполняется по всей цепочке. Однако если требуется глубокая запись и удаление, легко создать подкласс, который будет обновлять ключи, найденные глубже в цепочке:117118```python119class DeepChainMap(ChainMap):120 'Variant of ChainMap that allows direct updates to inner scopes'121122 def __setitem__(self, key, value):123 for mapping in self.maps:124 if key in mapping:125 mapping[key] = value126 return127 self.maps[0][key] = value128129 def __delitem__(self, key):130 for mapping in self.maps:131 if key in mapping:132 del mapping[key]133 return134 raise KeyError(key)135136>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})137>>> d['lion'] = 'orange' # обновить существующий ключ на два уровня ниже138>>> d['snake'] = 'red' # новые ключи добавляются в самый верхний словарь139>>> del d['elephant'] # удалить существующий ключ на один уровень ниже140DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})141```142143## 8.3.2. [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) объекты144145Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:146147```python148>>> # Подсчитать вхождения слов в списке149>>> cnt = Counter()150>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:151... cnt[word] += 1152>>> cnt153Counter({'blue': 3, 'red': 2, 'green': 1})154155>>> # Найти десять самых распространённых слов в «Гамлете»156>>> import re157>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())158>>> Counter(words).most_common(10)159[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),160 ('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]161```162163#### `class collections.Counter([iterable-or-mapping])`164165[`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) – это подкласс [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict) для подсчёта хешируемых объектов. Это неупорядоченная коллекция, в которой элементы хранятся как ключи словаря, а их количества – как значения словаря. Количества могут быть любыми целыми числами, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) аналогичен мультимножествам (bags или multisets) в других языках.166167Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):168169```python170>>> c = Counter() # новый пустой счётчик171>>> c = Counter('gallahad') # новый счётчик из итерируемого объекта172>>> c = Counter({'red': 4, 'blue': 2}) # новый счётчик из отображения173>>> c = Counter(cats=4, dogs=8) # новый счётчик из именованных аргументов174```175176Объекты Counter имеют интерфейс словаря, за исключением того, что при отсутствии элемента они возвращают нулевой счёт вместо возбуждения [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError):177178```python179>>> c = Counter(['eggs', 'ham'])180>>> c['bacon'] # счёт отсутствующего элемента равен нулю1810182```183184Установка счёта в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:185186```python187>>> c['sausage'] = 0 # запись счётчика с нулевым значением188>>> del c['sausage'] # del действительно удаляет запись189```190191Новое в версии 3.1.192193Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:194195#### `elements()`196197Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его счёте. Элементы возвращаются в произвольном порядке. Если счёт элемента меньше единицы, [`elements()`](https://python-all.ru/3.3/library/collections.html#collections.Counter.elements) игнорирует его.198199```python200>>> c = Counter(a=4, b=2, c=0, d=-2)201>>> list(c.elements())202['a', 'a', 'a', 'a', 'b', 'b']203```204205#### `most_common([n])`206207Возвращает список из *n* наиболее часто встречающихся элементов и их количество, от самого частого к самому редкому. Если *n* не указан, [`most_common()`](https://python-all.ru/3.3/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковым количеством упорядочиваются произвольно:208209```python210>>> Counter('abracadabra').most_common(3)211[('a', 5), ('r', 2), ('b', 2)]212```213214#### `subtract([iterable-or-mapping])`215216Элементы вычитаются из *iterable* или из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.3/library/stdtypes.html#dict.update), но вычитает счёты вместо их замены. И входные, и выходные значения могут быть нулевыми или отрицательными.217218```python219>>> c = Counter(a=4, b=2, c=0, d=-2)220>>> d = Counter(a=1, b=2, c=3, d=4)221>>> c.subtract(d)222>>> c223Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})224```225226Новое в версии 3.2.227228Для объектов [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) доступны обычные методы словаря, за исключением двух, которые работают иначе для счётчиков.229230#### `fromkeys(iterable)`231232Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter).233234#### `update([iterable-or-mapping])`235236Элементы подсчитываются из *iterable* или добавляются из другого *mapping* (или счётчика). Как [`dict.update()`](https://python-all.ru/3.3/library/stdtypes.html#dict.update), но добавляет счёты вместо их замены. Кроме того, *iterable* должен быть последовательностью элементов, а не последовательностью пар `(key, value)`.237238Распространённые приёмы работы с объектами [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter):239240```python241sum(c.values()) # сумма всех значений242c.clear() # сбросить все значения243list(c) # список уникальных элементов244set(c) # преобразовать в множество245dict(c) # преобразовать в обычный словарь246c.items() # преобразовать в список пар (elem, cnt)247Counter(dict(list_of_pairs)) # создать из списка пар (элемент, кол-во)248c.most_common()[:-n-1:-1] # n наименее частых элементов249+c # удалить нулевые и отрицательные значения250```251252Для объединения объектов [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) в мультимножества (счётчики, в которых счёты больше нуля) предусмотрено несколько математических операций. Сложение и вычитание объединяют счётчики путём сложения или вычитания счётов соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих счётов. Каждая операция может принимать входные данные со знаковыми счётами, но на выходе будут исключены результаты со счётом ноль или меньше.253254```python255>>> c = Counter(a=3, b=1)256>>> d = Counter(a=1, b=2)257>>> c + d # сложение двух счётчиков: c[x] + d[x]258Counter({'a': 4, 'b': 3})259>>> c - d # вычитание (остаются только положительные значения)260Counter({'a': 2})261>>> c & d # пересечение: min(c[x], d[x])262Counter({'a': 1, 'b': 1})263>>> c | d # объединение: max(c[x], d[x])264Counter({'a': 3, 'b': 2})265```266267Унарное сложение и вычитание – это сокращённая запись для добавления пустого счётчика или вычитания из пустого счётчика.268269```python270>>> c = Counter(a=2, b=-4)271>>> +c272Counter({'a': 2})273>>> -c274Counter({'b': 4})275```276277Новое в версии 3.3: Добавлена поддержка унарного плюса, унарного минуса и операций над мультимножествами на месте.278279> **Примечание**280>281> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.282>283> - Сам класс [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения предназначены для чисел, представляющих счёты, но в поле значения *можно* хранить что угодно.284> - Метод `most_common()` требует только, чтобы значения были упорядочиваемыми.285> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа подойдут, а отрицательные значения поддерживаются. То же самое верно для `update()` и `subtract()`, которые допускают отрицательные и нулевые значения как на входе, так и на выходе.286> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.287> - Метод `elements()` требует целочисленных счётов. Он игнорирует нулевые и отрицательные счёты.288289> **См. также**290>291> - [Класс Counter](https://python-all.ru/3.3/library/collections.html) адаптирован для Python 2.5 и раннего [рецепта Bag](https://python-all.ru/3.3/library/collections.html) для Python 2.4.292> - [Класс Bag](https://python-all.ru/3.3/library/collections.html) в Smalltalk.293> - Статья в Википедии о [мультимножествах](https://python-all.ru/3.3/library/collections.html).294> - [Мультимножества в C++](https://python-all.ru/3.3/library/collections.html): учебное пособие с примерами.295> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.296> - Чтобы перечислить все различные мультимножества заданного размера из заданного набора элементов, см. [`itertools.combinations_with_replacement()`](https://python-all.ru/3.3/library/itertools.html#itertools.combinations_with_replacement).297>298> > map(Counter, combinations\_with\_replacement(‘ABC’, 2)) –\> AA AB AC BB BC CC299300## 8.3.3. [`deque`](https://python-all.ru/3.3/library/collections.html#collections.deque) объекты301302#### `class collections.deque([iterable[, maxlen]])`303304Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.3/library/collections.html#collections.deque.append)) данными из *iterable*. Если *iterable* не указан, новый deque пуст.305306Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.307308Хотя объекты [`list`](https://python-all.ru/3.3/library/stdtypes.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и несут затраты памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.309310Если *maxlen* не указан или равен *None*, deque могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque с ограниченной длиной заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.311312Объекты deque поддерживают следующие методы:313314#### `append(x)`315316Добавляет *x* в правую часть deque.317318#### `appendleft(x)`319320Добавляет *x* в левую часть deque.321322#### `clear()`323324Удаляет все элементы из deque, после чего его длина равна 0.325326#### `count(x)`327328Подсчитывает количество элементов deque, равных *x*.329330Новое в версии 3.2.331332#### `extend(iterable)`333334Расширяет правую часть deque, добавляя элементы из итерируемого объекта.335336#### `extendleft(iterable)`337338Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.339340#### `pop()`341342Удаляет и возвращает элемент с правой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.3/library/exceptions.html#IndexError).343344#### `popleft()`345346Удаляет и возвращает элемент с левой стороны deque. Если элементов нет, возбуждает [`IndexError`](https://python-all.ru/3.3/library/exceptions.html#IndexError).347348#### `remove(value)`349350Удаляет первое вхождение *value*. Если не найдено, возбуждает [`ValueError`](https://python-all.ru/3.3/library/exceptions.html#ValueError).351352#### `reverse()`353354Переворачивает элементы deque по месту и затем возвращает `None`.355356Новое в версии 3.2.357358#### `rotate(n)`359360Поворачивает deque на *n* шагов вправо. Если *n* отрицательно, поворачивает влево. Поворот на один шаг вправо эквивалентен: `d.appendleft(d.pop())`.361362Объекты deque также предоставляют один атрибут только для чтения:363364#### `maxlen`365366Максимальный размер deque или *None*, если неограничен.367368Новое в версии 3.1.369370В дополнение к вышеперечисленному, двусторонние очереди поддерживают итерацию, сериализацию, `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.3/reference/expressions.html#in) и доступ по индексу, например `d[-1]`. Индексированный доступ занимает O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа используйте списки.371372Пример:373374```python375>>> from collections import deque376>>> d = deque('ghi') # создать новый deque с тремя элементами377>>> for elem in d: # обход элементов deque378... print(elem.upper())379G380H381I382383>>> d.append('j') # добавить новый элемент справа384>>> d.appendleft('f') # добавить новый элемент слева385>>> d # показать представление deque386deque(['f', 'g', 'h', 'i', 'j'])387388>>> d.pop() # вернуть и удалить правый элемент389'j'390>>> d.popleft() # вернуть и удалить левый элемент391'f'392>>> list(d) # вывести содержимое deque393['g', 'h', 'i']394>>> d[0] # посмотреть левый элемент395'g'396>>> d[-1] # посмотреть правый элемент397'i'398399>>> list(reversed(d)) # вывести содержимое deque в обратном порядке400['i', 'h', 'g']401>>> 'h' in d # поиск в deque402True403>>> d.extend('jkl') # добавить несколько элементов за раз404>>> d405deque(['g', 'h', 'i', 'j', 'k', 'l'])406>>> d.rotate(1) # поворот вправо407>>> d408deque(['l', 'g', 'h', 'i', 'j', 'k'])409>>> d.rotate(-1) # поворот влево410>>> d411deque(['g', 'h', 'i', 'j', 'k', 'l'])412413>>> deque(reversed(d)) # создать новую deque в обратном порядке414deque(['l', 'k', 'j', 'i', 'h', 'g'])415>>> d.clear() # очистить deque416>>> d.pop() # невозможно извлечь элемент из пустой deque417Traceback (most recent call last):418 File "<pyshell#6>", line 1, in -toplevel-419 d.pop()420IndexError: pop from an empty deque421422>>> d.extendleft('abc') # extendleft() меняет порядок ввода на обратный423>>> d424deque(['c', 'b', 'a'])425```426427### 8.3.3.1. [`deque`](https://python-all.ru/3.3/library/collections.html#collections.deque) Рецепты428429В этом разделе рассматриваются различные подходы к работе с деками.430431Двусторонние очереди с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:432433```python434def tail(filename, n=10):435 'Return the last n lines of a file'436 with open(filename) as f:437 return deque(f, n)438```439440Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:441442```python443def moving_average(iterable, n=3):444 # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0445 # http://en.wikipedia.org/wiki/Moving_average446 it = iter(iterable)447 d = deque(itertools.islice(it, n-1))448 d.appendleft(0)449 s = sum(d)450 for elem in it:451 s += elem - d.popleft()452 d.append(elem)453 yield s / n454```455456Метод `rotate()` предоставляет способ реализовать срезы и удаление для [`deque`](https://python-all.ru/3.3/library/collections.html#collections.deque). Например, чистая реализация Python для `del d[n]` опирается на метод `rotate()` для позиционирования элементов, которые нужно извлечь:457458```python459def delete_nth(d, n):460 d.rotate(-n)461 d.popleft()462 d.rotate(n)463```464465Чтобы реализовать срезы для [`deque`](https://python-all.ru/3.3/library/collections.html#collections.deque), используйте аналогичный подход, применяя `rotate()` для перемещения целевого элемента к левой стороне deque. Удалите старые записи с помощью `popleft()`, добавьте новые с помощью `extend()`, а затем обратите вращение. С небольшими вариациями этого подхода легко реализовать стековые манипуляции в стиле Forth, такие как `dup`, `drop`, `swap`, `over`, `pick`, `rot` и `roll`.466467## 8.3.4. [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) объекты468469#### `class collections.defaultdict([default_factory[, ...]])`470471Возвращает новый объект, подобный словарю. [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict), и здесь не документируется.472473Первый аргумент задаёт начальное значение для атрибута [`default_factory`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.default_factory); по умолчанию `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict), включая именованные аргументы.474475Объекты [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict):476477#### `__missing__(key)`478479Если атрибут [`default_factory`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.default_factory) равен `None`, это возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError) с *key* в качестве аргумента.480481Если [`default_factory`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов, чтобы предоставить значение по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.482483Если вызов [`default_factory`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.default_factory) возбуждает исключение, это исключение распространяется без изменений.484485Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict), когда запрошенный ключ не найден; то, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__getitem__).486487Обратите внимание, что [`__missing__()`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.__missing__) *не* вызывается для любых операций, кроме [`__getitem__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__getitem__). Это означает, что `get()`, как и обычные словари, будет возвращать `None` в качестве значения по умолчанию, а не использовать [`default_factory`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.default_factory).488489Объекты [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) поддерживают следующую переменную экземпляра:490491#### `default_factory`492493Этот атрибут используется методом [`__missing__()`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он присутствует, или `None`, если отсутствует.494495### 8.3.4.1. [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) Примеры496497Используя [`list`](https://python-all.ru/3.3/library/stdtypes.html#list) в качестве `default_factory`, легко сгруппировать последовательность пар ключ-значение в словарь списков:498499```python500>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]501>>> d = defaultdict(list)502>>> for k, v in s:503... d[k].append(v)504...505>>> list(d.items())506[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]507```508509Когда ключ встречается впервые, его ещё нет в отображении; поэтому запись автоматически создаётся с помощью функции `default_factory`, которая возвращает пустой [`list`](https://python-all.ru/3.3/library/stdtypes.html#list). Затем операция `list.append()` добавляет значение в новый список. При повторной встрече ключа поиск происходит обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет ещё одно значение в список. Этот метод проще и быстрее, чем эквивалентный приём с [`dict.setdefault()`](https://python-all.ru/3.3/library/stdtypes.html#dict.setdefault):510511```python512>>> d = {}513>>> for k, v in s:514... d.setdefault(k, []).append(v)515...516>>> list(d.items())517[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]518```519520Установка `default_factory` в [`int`](https://python-all.ru/3.3/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) полезным для подсчёта (как мешок или мультимножество в других языках):521522```python523>>> s = 'mississippi'524>>> d = defaultdict(int)525>>> for k in s:526... d[k] += 1527...528>>> list(d.items())529[('i', 4), ('p', 2), ('s', 4), ('m', 1)]530```531532Когда буква встречается впервые, она отсутствует в отображении, поэтому функция `default_factory` вызывает [`int()`](https://python-all.ru/3.3/library/functions.html#int), чтобы получить нулевое значение по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.533534Функция [`int()`](https://python-all.ru/3.3/library/functions.html#int), которая всегда возвращает ноль, – всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):535536```python537>>> def constant_factory(value):538... return lambda: value539>>> d = defaultdict(constant_factory('<missing>'))540>>> d.update(name='John', action='ran')541>>> '%(name)s %(action)s to %(object)s' % d542'John ran to <missing>'543```544545Установка `default_factory` в [`set`](https://python-all.ru/3.3/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.3/library/collections.html#collections.defaultdict) полезным для построения словаря множеств:546547```python548>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]549>>> d = defaultdict(set)550>>> for k, v in s:551... d[k].add(v)552...553>>> list(d.items())554[('blue', {2, 4}), ('red', {1, 3})]555```556557## 8.3.5. Фабричная функция [`namedtuple()`](https://python-all.ru/3.3/library/collections.html#collections.namedtuple) для кортежей с именованными полями558559Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.560561#### `collections.namedtuple(typename, field_names, verbose=False, rename=False)`562563Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежу, поля которых доступны через обращение к атрибутам, а также индексируемы и итерируемы. Экземпляры подкласса также имеют полезную docstring (с именем типа и полями) и полезный метод [`__repr__()`](https://python-all.ru/3.3/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.564565Параметр *field\_names* может быть строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`. Как вариант, *field\_names* может быть последовательностью строк, например `['x', 'y']`.566567В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и подчёркиваний, но не начинаются с цифры или подчёркивания и не могут быть [`ключевым словом`](https://python-all.ru/3.3/library/keyword.html#module-keyword), таким как *class*, *for*, *return*, *global*, *pass* или *raise*.568569Если *rename* равно true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, удаляя ключевое слово `def` и дублирующееся имя поля `abc`.570571Если *verbose* равно true, определение класса выводится после его создания. Эта опция устарела; вместо этого проще вывести атрибут `_source`.572573Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.574575Изменено в версии 3.1: Добавлена поддержка *rename*.576577```python578>>> # Базовый пример579>>> Point = namedtuple('Point', ['x', 'y'])580>>> p = Point(11, y=22) # создать экземпляр с позиционными или именованными аргументами581>>> p[0] + p[1] # доступен по индексу, как обычный кортеж (11, 22)58233583>>> x, y = p # распаковывается как обычный кортеж584>>> x, y585(11, 22)586>>> p.x + p.y # поля также доступны по имени58733588>>> p # читаемое __repr__ в стиле name=value589Point(x=11, y=22)590```591592Именованные кортежи особенно полезны для присвоения имён полям кортежам результатов, возвращаемым модулями [`csv`](https://python-all.ru/3.3/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.3/library/sqlite3.html#module-sqlite3):593594```python595EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')596597import csv598for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):599 print(emp.name, emp.title)600601import sqlite3602conn = sqlite3.connect('/companydata')603cursor = conn.cursor()604cursor.execute('SELECT name, age, title, department, paygrade FROM employees')605for emp in map(EmployeeRecord._make, cursor.fetchall()):606 print(emp.name, emp.title)607```608609В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и два атрибута. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.610611#### `classmethod somenamedtuple._make(iterable)`612613Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.614615```python616>>> t = [11, 22]617>>> Point._make(t)618Point(x=11, y=22)619```620621#### `somenamedtuple._asdict()`622623Возвращает новый [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict), который сопоставляет имена полей с их соответствующими значениями. Обратите внимание, что этот метод больше не нужен, поскольку того же эффекта можно достичь с помощью встроенной функции [`vars()`](https://python-all.ru/3.3/library/functions.html#vars):624625```python626>>> vars(p)627OrderedDict([('x', 11), ('y', 22)])628```629630Изменено в версии 3.1: Возвращает [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict).631632#### `somenamedtuple._replace(kwargs)`633634Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:635636```python637>>> p = Point(x=11, y=22)638>>> p._replace(x=33)639Point(x=33, y=22)640641>>> for partnum, record in inventory.items():642... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())643```644645#### `somenamedtuple._source`646647Строка с исходным кодом на чистом Python, использованным для создания класса именованного кортежа. Исходный код делает именованный кортеж самодокументируемым. Его можно вывести на печать, выполнить с помощью [`exec()`](https://python-all.ru/3.3/library/functions.html#exec) или сохранить в файл и импортировать.648649Новое в версии 3.3.650651#### `somenamedtuple._fields`652653Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.654655```python656>>> p._fields # просмотреть имена полей657('x', 'y')658659>>> Color = namedtuple('Color', 'red green blue')660>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)661>>> Pixel(11, 22, 128, 255, 0)662Pixel(x=11, y=22, red=128, green=255, blue=0)663```664665Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.3/library/functions.html#getattr):666667```python668>>> getattr(p, 'x')66911670```671672Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [*Распаковка списков аргументов*](https://python-all.ru/3.3/tutorial/controlflow.html#tut-unpacking-arguments)):673674```python675>>> d = {'x': 11, 'y': 22}676>>> Point(**d)677Point(x=11, y=22)678```679680Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:681682```python683>>> class Point(namedtuple('Point', 'x y')):684 __slots__ = ()685 @property686 def hypot(self):687 return (self.x ** 2 + self.y ** 2) ** 0.5688 def __str__(self):689 return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)690```691692```python693>>> for p in Point(3, 4), Point(14, 5/7):694 print(p)695Point: x= 3.000 y= 4.000 hypot= 5.000696Point: x=14.000 y= 0.714 hypot=14.018697```698699Приведённый выше подкласс устанавливает `__slots__` в пустой кортеж. Это помогает снизить потребление памяти, предотвращая создание словарей экземпляров.700701Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа на основе атрибута `_fields`:702703```python704>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))705```706707Значения по умолчанию можно реализовать, используя `_replace()` для настройки экземпляра-прототипа:708709```python710>>> Account = namedtuple('Account', 'owner balance transaction_count')711>>> default_account = Account('<owner name>', 0.0, 0)712>>> johns_account = default_account._replace(owner='John')713>>> janes_account = default_account._replace(owner='Jane')714```715716Перечислимые константы можно реализовать с помощью именованных кортежей, но проще и эффективнее использовать простое объявление класса:717718```python719>>> Status = namedtuple('Status', 'open pending closed')._make(range(3))720>>> Status.open, Status.pending, Status.closed721(0, 1, 2)722>>> class Status:723 open, pending, closed = range(3)724```725726> **См. также**727>728> - [Рецепт именованного кортежа](https://python-all.ru/3.3/library/collections.html) адаптирован для Python 2.4.729> - [Рецепт абстрактного базового класса именованного кортежа с примесью метакласса](https://python-all.ru/3.3/library/collections.html) от Яна Калишевского. Кроме предоставления [*абстрактного базового класса*](https://python-all.ru/3.3/glossary.html#term-abstract-base-class) для именованных кортежей, он также поддерживает альтернативный конструктор на основе [*метакласса*](https://python-all.ru/3.3/glossary.html#term-metaclass), что удобно для случаев, когда именованные кортежи наследуются.730731## 8.3.6. Объекты [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict)732733Упорядоченные словари работают как обычные словари, но запоминают порядок, в котором были добавлены элементы. При итерации по упорядоченному словарю элементы возвращаются в том порядке, в котором их ключи были впервые добавлены.734735#### `class collections.OrderedDict([items])`736737Возвращает экземпляр подкласса dict, поддерживающий обычные методы [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict). *OrderedDict* – это словарь, который запоминает порядок, в котором ключи были вставлены впервые. Если новая запись перезаписывает существующую, исходная позиция вставки остаётся неизменной. Удаление записи и повторная вставка перемещает её в конец.738739Новое в версии 3.1.740741#### `popitem(last=True)`742743Метод [`popitem()`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (ключ, значение). Пары возвращаются в порядке LIFO, если *last* равно true, или в порядке FIFO, если false.744745#### `move_to_end(key, last=True)`746747Перемещает существующий *ключ* на любой конец упорядоченного словаря. Элемент перемещается в правый конец, если *last* равно true (по умолчанию), или в начало, если *last* равно false. Возбуждает [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если *ключ* не существует:748749```python750>>> d = OrderedDict.fromkeys('abcde')751>>> d.move_to_end('b')752>>> ''.join(d.keys())753'acdeb'754>>> d.move_to_end('b', last=False)755>>> ''.join(d.keys())756'bacde'757```758759Новое в версии 3.2.760761В дополнение к обычным методам отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.3/library/functions.html#reversed).762763Проверки на равенство между объектами [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) чувствительны к порядку и реализованы как `list(od1.items())==list(od2.items())`. Проверки на равенство между объектами [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/3.3/library/collections.abc.html#collections.abc.Mapping) не чувствительны к порядку, как обычные словари. Это позволяет объектам [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) использоваться вместо обычного словаря где угодно.764765Конструктор [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) и метод `update()` оба принимают именованные аргументы, но их порядок теряется, поскольку семантика вызова функций Python передаёт именованные аргументы с помощью обычного неупорядоченного словаря.766767> **См. также**768>769> [Эквивалентный рецепт OrderedDict](https://python-all.ru/3.3/library/collections.html) , работающий на Python 2.4 или новее.770771### 8.3.6.1. [`OrderedDict`](https://python-all.ru/3.3/library/collections.html#collections.OrderedDict) Примеры и рецепты772773Поскольку упорядоченный словарь запоминает порядок вставки, его можно использовать в сочетании с сортировкой для создания отсортированного словаря:774775```python776>>> # обычный неотсортированный словарь777>>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}778779>>> # словарь, отсортированный по ключу780>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))781OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])782783>>> # словарь, отсортированный по значению784>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))785OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])786787>>> # словарь, отсортированный по длине строки ключа788>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))789OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])790```791792Новые отсортированные словари сохраняют порядок сортировки при удалении записей. Но при добавлении новых ключей они добавляются в конец, и сортировка не сохраняется.793794Также несложно создать вариант упорядоченного словаря, который запоминает порядок, в котором ключи были *в последний раз* вставлены. Если новая запись перезаписывает существующую, исходная позиция вставки меняется и перемещается в конец:795796```python797class LastUpdatedOrderedDict(OrderedDict):798 'Store items in the order the keys were last added'799800 def __setitem__(self, key, value):801 if key in self:802 del self[key]803 OrderedDict.__setitem__(self, key, value)804```805806Упорядоченный словарь можно комбинировать с классом [`Counter`](https://python-all.ru/3.3/library/collections.html#collections.Counter), чтобы счётчик запоминал порядок, в котором элементы встретились впервые:807808```python809class OrderedCounter(Counter, OrderedDict):810 'Counter that remembers the order elements are first encountered'811812 def __repr__(self):813 return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))814815 def __reduce__(self):816 return self.__class__, (OrderedDict(self),)817```818819## 8.3.7. Объекты [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict)820821Класс [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов словаря. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`dict`](https://python-all.ru/3.3/library/stdtypes.html#dict); однако с этим классом может быть проще работать, потому что базовый словарь доступен как атрибут.822823#### `class collections.UserDict([initialdata])`824825Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, который доступен через атрибут [`data`](https://python-all.ru/3.3/library/collections.html#collections.UserDict.data) объектов [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict). Если передан *initialdata*, то [`data`](https://python-all.ru/3.3/library/collections.html#collections.UserDict.data) инициализируется его содержимым; обратите внимание, что ссылка на *initialdata* не сохраняется, что позволяет использовать его для других целей.826827В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict) предоставляют следующий атрибут:828829#### `data`830831Настоящий словарь, используемый для хранения содержимого класса [`UserDict`](https://python-all.ru/3.3/library/collections.html#collections.UserDict).832833## 8.3.8. Объекты [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList)834835Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.836837Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`list`](https://python-all.ru/3.3/library/stdtypes.html#list); однако с этим классом может быть проще работать, потому что базовый список доступен как атрибут.838839#### `class collections.UserList([list])`840841Класс, имитирующий список. Содержимое экземпляра хранится в обычном списке, который доступен через атрибут [`data`](https://python-all.ru/3.3/library/collections.html#collections.UserList.data) объектов [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList). Содержимое экземпляра изначально устанавливается в копию *list*, по умолчанию пустой список `[]`. *list* может быть любым итерируемым объектом, например, настоящим списком Python или объектом [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList).842843В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList) предоставляют следующий атрибут:844845#### `data`846847Настоящий объект [`list`](https://python-all.ru/3.3/library/stdtypes.html#list), используемый для хранения содержимого класса [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList).848849**Требования к созданию подклассов:** Ожидается, что подклассы [`UserList`](https://python-all.ru/3.3/library/collections.html#collections.UserList) предоставляют конструктор, который может быть вызван без аргументов или с одним аргументом. Операции со списком, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром, являющимся объектом последовательности, используемым в качестве источника данных.850851Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.852853## 8.3.9. Объекты [`UserString`](https://python-all.ru/3.3/library/collections.html#collections.UserString)854855Класс [`UserString`](https://python-all.ru/3.3/library/collections.html#collections.UserString) действует как обёртка вокруг строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создавать подклассы напрямую от [`str`](https://python-all.ru/3.3/library/stdtypes.html#str); однако с этим классом может быть проще работать, потому что базовая строка доступна как атрибут.856857#### `class collections.UserString([sequence])`858859Класс, имитирующий строку или объект строки Unicode. Содержимое экземпляра хранится в обычном строковом объекте, который доступен через атрибут `data` объектов [`UserString`](https://python-all.ru/3.3/library/collections.html#collections.UserString). Содержимое экземпляра изначально устанавливается в копию *sequence*. *sequence* может быть экземпляром [`bytes`](https://python-all.ru/3.3/library/functions.html#bytes), [`str`](https://python-all.ru/3.3/library/stdtypes.html#str), [`UserString`](https://python-all.ru/3.3/library/collections.html#collections.UserString) (или подклассом) или произвольной последовательностью, которая может быть преобразована в строку с помощью встроенной функции [`str()`](https://python-all.ru/3.3/library/stdtypes.html#str).860