collections.md
1> **Источник:** https://python-all.ru/3.8/library/collections.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`collections`](https://python-all.ru/3.8/library/collections.html#module-collections) – Типы данных-контейнеры89**Исходный код:** [Lib/collections/\_\_init\_\_.py](https://python-all.ru/src/3.8/Lib/collections/__init__.py)1011---1213Этот модуль предоставляет специализированные типы данных-контейнеры в качестве альтернативы встроенным контейнерам общего назначения Python: [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), [`list`](https://python-all.ru/3.8/library/stdtypes.html#list), [`set`](https://python-all.ru/3.8/library/stdtypes.html#set) и [`tuple`](https://python-all.ru/3.8/library/stdtypes.html#tuple).1415| [`namedtuple()`](https://python-all.ru/3.8/library/collections.html#collections.namedtuple) | фабричная функция для создания подклассов кортежей с именованными полями |16| --- | --- |17| [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque) | контейнер, подобный списку, с быстрыми добавлением и извлечением с обоих концов |18| [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) | класс, подобный словарю, для создания единого представления нескольких отображений |19| [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) | подкласс dict для подсчёта хэшируемых объектов |20| [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) | подкласс dict, который запоминает порядок добавления записей |21| [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) | подкласс dict, который вызывает фабричную функцию для предоставления отсутствующих значений |22| [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict) | обёртка вокруг словарей для упрощения создания подклассов dict |23| [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList) | обёртка вокруг списков для упрощения создания подклассов list |24| [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString) | обёртка вокруг строк для упрощения создания подклассов str |2526Устарело с версии 3.3, будет удалено в версии 3.10: Модуль [Collections Abstract Base Classes](https://python-all.ru/3.8/library/collections.abc.html#collections-abstract-base-classes) перенесён в [`collections.abc`](https://python-all.ru/3.8/library/collections.abc.html#module-collections.abc). Для обратной совместимости они продолжают отображаться в этом модуле до версии Python 3.9.2728## [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) объекты2930Новое в версии 3.3.3132Класс [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) предназначен для быстрой связки нескольких отображений, чтобы их можно было рассматривать как единое целое. Часто он работает намного быстрее, чем создание нового словаря и выполнение нескольких вызовов [`update()`](https://python-all.ru/3.8/library/stdtypes.html#dict.update).3334Класс можно использовать для имитации вложенных областей видимости; он полезен в шаблонизаторах.3536#### `class collections.ChainMap(*maps)`3738[`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) группирует несколько словарей или других отображений вместе, создавая единое обновляемое представление. Если не указаны *maps*, создаётся один пустой словарь, так что новая цепочка всегда содержит как минимум одно отображение.3940Базовые отображения хранятся в списке. Этот список является открытым; к нему можно обращаться или изменять его через атрибут *maps*. Других состояний нет.4142При поиске последовательно просматриваются базовые отображения, пока не будет найден ключ. В отличие от этого, записи, обновления и удаления работают только с первым отображением.4344[`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) включает базовые отображения по ссылке. То есть, если одно из базовых отображений будет обновлено, эти изменения отразятся в [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap).4546Поддерживаются все обычные методы словаря. Кроме того, имеется атрибут *maps*, метод для создания новых подконтекстов и свойство для доступа ко всем отображениям, кроме первого:4748#### `maps`4950Обновляемый пользователем список отображений. Список упорядочен от первого просматриваемого к последнему. Это единственное сохраняемое состояние, и его можно изменять, чтобы менять порядок поиска отображений. Список всегда должен содержать хотя бы одно отображение.5152#### `new_child(m=None)`5354Возвращает новый объект [`ChainMap`](https://python-all.ru/3.8/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.8/library/collections.html#collections.ChainMap), содержащий все отображения из текущего экземпляра, кроме первого. Это полезно для пропуска первого отображения при поиске. Варианты использования аналогичны ключевому слову [`nonlocal`](https://python-all.ru/3.8/reference/simple_stmts.html#nonlocal), применяемому в [вложенных областях видимости](https://python-all.ru/3.8/glossary.html#term-nested-scope). Также они параллельны встроенной функции [`super()`](https://python-all.ru/3.8/library/functions.html#super). Ссылка на `d.parents` эквивалентна: `ChainMap(*d.maps[1:])`.6162Обратите внимание, порядок итерации [`ChainMap()`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) определяется сканированием отображений от последнего к первому:6364```python65>>> baseline = {'music': 'bach', 'art': 'rembrandt'}66>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}67>>> list(ChainMap(adjustments, baseline))68['music', 'art', 'opera']69```7071Это даёт тот же порядок, что и серия вызовов [`dict.update()`](https://python-all.ru/3.8/library/stdtypes.html#dict.update), начиная с последнего отображения:7273```python74>>> combined = baseline.copy()75>>> combined.update(adjustments)76>>> list(combined)77['music', 'art', 'opera']78```7980> **См. также**81>82> - Класс [MultiContext](https://python-all.ru/3.8/library/collections.html) в пакете Enthought [CodeTools](https://python-all.ru/3.8/library/collections.html) имеет опции для поддержки записи в любое отображение в цепочке.83> - Класс [Context](https://python-all.ru/3.8/library/collections.html) в Django для шаблонов представляет собой цепочку отображений только для чтения. Он также поддерживает добавление и удаление контекстов, аналогично методу [`new_child()`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap.new_child) и свойству [`parents`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap.parents).84> - Рецепт [Nested Contexts](https://python-all.ru/3.8/library/collections.html) содержит опции для управления тем, применяются ли записи и другие изменения только к первому отображению или к любому отображению в цепочке.85> - [Сильно упрощённая версия Chainmap только для чтения](https://python-all.ru/3.8/library/collections.html).8687### [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) Примеры и рецепты8889В этом разделе показаны различные подходы к работе с цепочечными отображениями.9091Пример симуляции внутренней цепочки поиска Python:9293```python94import builtins95pylookup = ChainMap(locals(), globals(), vars(builtins))96```9798Пример, когда заданные пользователем аргументы командной строки имеют приоритет над переменными окружения, которые, в свою очередь, имеют приоритет над значениями по умолчанию:99100```python101import os, argparse102103defaults = {'color': 'red', 'user': 'guest'}104105parser = argparse.ArgumentParser()106parser.add_argument('-u', '--user')107parser.add_argument('-c', '--color')108namespace = parser.parse_args()109command_line_args = {k: v for k, v in vars(namespace).items() if v is not None}110111combined = ChainMap(command_line_args, os.environ, defaults)112print(combined['color'])113print(combined['user'])114```115116Примеры шаблонов использования класса [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) для симуляции вложенных контекстов:117118```python119c = ChainMap() # Создать корневой контекст120d = c.new_child() # Создать вложенный дочерний контекст121e = c.new_child() # Дочерний контекст c, независимый от d122e.maps[0] # Словарь текущего контекста – как locals() в Python123e.maps[-1] # Корневой контекст – как globals() в Python124e.parents # Цепочка объемлющих контекстов – как nonlocals в Python125126d['x'] = 1 # Установить значение в текущем контексте127d['x'] # Получить первый ключ в цепочке контекстов128del d['x'] # Удалить из текущего контекста129list(d) # Все вложенные значения130k in d # Проверить все вложенные значения131len(d) # Количество вложенных значений132d.items() # Все вложенные элементы133dict(d) # Развернуть в обычный словарь134```135136Класс [`ChainMap`](https://python-all.ru/3.8/library/collections.html#collections.ChainMap) выполняет обновления (запись и удаление) только в первом отображении цепочки, в то время как поиск просматривает всю цепочку. Однако, если требуется глубокая запись и удаление, легко создать подкласс, который обновляет ключи, найденные глубже в цепочке:137138```python139class DeepChainMap(ChainMap):140 'Variant of ChainMap that allows direct updates to inner scopes'141142 def __setitem__(self, key, value):143 for mapping in self.maps:144 if key in mapping:145 mapping[key] = value146 return147 self.maps[0][key] = value148149 def __delitem__(self, key):150 for mapping in self.maps:151 if key in mapping:152 del mapping[key]153 return154 raise KeyError(key)155156>>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'})157>>> d['lion'] = 'orange' # обновить существующий ключ на два уровня ниже158>>> d['snake'] = 'red' # новые ключи добавляются в самый верхний словарь159>>> del d['elephant'] # удалить существующий ключ на один уровень ниже160>>> d # отобразить результат161DeepChainMap({'zebra': 'black', 'snake': 'red'}, {}, {'lion': 'orange'})162```163164## [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) объекты165166Предоставляется инструмент счётчика для удобного и быстрого подсчёта. Например:167168```python169>>> # Подсчитать вхождения слов в списке170>>> cnt = Counter()171>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:172... cnt[word] += 1173>>> cnt174Counter({'blue': 3, 'red': 2, 'green': 1})175176>>> # Найти десять самых распространённых слов в «Гамлете»177>>> import re178>>> words = re.findall(r'\w+', open('hamlet.txt').read().lower())179>>> Counter(words).most_common(10)180[('the', 1143), ('and', 966), ('to', 762), ('of', 669), ('i', 631),181 ('you', 554), ('a', 546), ('my', 514), ('hamlet', 471), ('in', 451)]182```183184#### `class collections.Counter([iterable-or-mapping])`185186Объект [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) является подклассом [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), предназначенным для подсчёта хэшируемых объектов. Это коллекция, в которой элементы хранятся как ключи словаря, а их количества – как значения словаря. Количества могут быть любыми целыми числами, включая ноль и отрицательные значения. Класс [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) аналогичен по смыслу мешку или мультимножеству в других языках.187188Элементы подсчитываются из *итерируемого объекта* или инициализируются из другого *отображения* (или счётчика):189190```python191>>> c = Counter() # новый пустой счётчик192>>> c = Counter('gallahad') # новый счётчик из итерируемого объекта193>>> c = Counter({'red': 4, 'blue': 2}) # новый счётчик из отображения194>>> c = Counter(cats=4, dogs=8) # новый счётчик из именованных аргументов195```196197Объекты Counter имеют интерфейс словаря, за исключением того, что они возвращают ноль для отсутствующих элементов вместо возбуждения [`KeyError`](https://python-all.ru/3.8/library/exceptions.html#KeyError):198199```python200>>> c = Counter(['eggs', 'ham'])201>>> c['bacon'] # счёт отсутствующего элемента равен нулю2020203```204205Установка количества в ноль не удаляет элемент из счётчика. Используйте `del` для полного удаления:206207```python208>>> c['sausage'] = 0 # запись счётчика с нулевым значением209>>> del c['sausage'] # del действительно удаляет запись210```211212Новое в версии 3.1.213214Изменено в версии 3.7: Будучи подклассом [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) унаследовал возможность запоминать порядок вставки. Математические операции над объектами *Counter* также сохраняют порядок. Результаты упорядочиваются сначала по времени первого появления элемента в левом операнде, а затем по порядку появления в правом операнде.215216Объекты Counter поддерживают три метода в дополнение к тем, что доступны для всех словарей:217218#### `elements()`219220Возвращает итератор по элементам, повторяя каждый столько раз, сколько указано в его количестве. Элементы возвращаются в порядке первого появления. Если количество элемента меньше единицы, [`elements()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.elements) игнорирует его.221222```python223>>> c = Counter(a=4, b=2, c=0, d=-2)224>>> sorted(c.elements())225['a', 'a', 'a', 'a', 'b', 'b']226```227228#### `most_common([n])`229230Возвращает список из *n* наиболее часто встречающихся элементов и их количества от самого частого к наименее частому. Если *n* опущено или `None`, [`most_common()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.most_common) возвращает *все* элементы счётчика. Элементы с одинаковым количеством упорядочиваются в порядке первого появления:231232```python233>>> Counter('abracadabra').most_common(3)234[('a', 5), ('b', 2), ('r', 2)]235```236237#### `subtract([iterable-or-mapping])`238239Элементы вычитаются из *итерируемого объекта* или из другого *отображения* (или счётчика). Подобно [`dict.update()`](https://python-all.ru/3.8/library/stdtypes.html#dict.update), но вычитает количества вместо замены. Как входные, так и выходные значения могут быть нулевыми или отрицательными.240241```python242>>> c = Counter(a=4, b=2, c=0, d=-2)243>>> d = Counter(a=1, b=2, c=3, d=4)244>>> c.subtract(d)245>>> c246Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})247```248249Новое в версии 3.2.250251Обычные методы словарей доступны для объектов [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter), за исключением двух, которые работают с счётчиками иначе.252253#### `fromkeys(iterable)`254255Этот метод класса не реализован для объектов [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter).256257#### `update([iterable-or-mapping])`258259Элементы подсчитываются из *итерируемого объекта* или добавляются из другого *отображения* (или счётчика). Как и [`dict.update()`](https://python-all.ru/3.8/library/stdtypes.html#dict.update), но увеличивает счётчики вместо их замены. Кроме того, *итерируемый объект* должен быть последовательностью элементов, а не последовательностью `(key, value)` пар.260261Типичные приёмы работы с объектами [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter):262263```python264sum(c.values()) # сумма всех значений265c.clear() # сбросить все значения266list(c) # список уникальных элементов267set(c) # преобразовать в множество268dict(c) # преобразовать в обычный словарь269c.items() # преобразовать в список пар (elem, cnt)270Counter(dict(list_of_pairs)) # создать из списка пар (элемент, кол-во)271c.most_common()[:-n-1:-1] # n наименее частых элементов272+c # удалить нулевые и отрицательные значения273```274275Для объединения объектов [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) в мультимножества (счётчики с положительными количествами) предоставляется несколько математических операций. Сложение и вычитание комбинируют счётчики, складывая или вычитая количества соответствующих элементов. Пересечение и объединение возвращают минимум и максимум соответствующих количеств. Каждая операция может принимать входные данные со знаковыми количествами, но в результате будут исключены значения с нулевыми или отрицательными количествами.276277```python278>>> c = Counter(a=3, b=1)279>>> d = Counter(a=1, b=2)280>>> c + d # сложение двух счётчиков: c[x] + d[x]281Counter({'a': 4, 'b': 3})282>>> c - d # вычитание (остаются только положительные значения)283Counter({'a': 2})284>>> c & d # пересечение: min(c[x], d[x]) 285Counter({'a': 1, 'b': 1})286>>> c | d # объединение: max(c[x], d[x])287Counter({'a': 3, 'b': 2})288```289290Унарное сложение и вычитание – это сокращения для добавления пустого счётчика или вычитания из пустого счётчика.291292```python293>>> c = Counter(a=2, b=-4)294>>> +c295Counter({'a': 2})296>>> -c297Counter({'b': 4})298```299300Новое в версии 3.3: Добавлена поддержка унарного плюса, унарного минуса и операций над мультимножествами на месте.301302> **Примечание**303>304> Счётчики в первую очередь предназначены для работы с положительными целыми числами для представления текущих счётчиков; однако была предпринята осторожность, чтобы излишне не исключать варианты использования, требующие других типов или отрицательных значений. Чтобы помочь с такими вариантами, в этом разделе описаны минимальные ограничения по диапазону и типам.305>306> - Сам класс [`Counter`](https://python-all.ru/3.8/library/collections.html#collections.Counter) является подклассом словаря без ограничений на ключи и значения. Значения должны быть числами, представляющими счётчики, но в поле значения *можно* хранить что угодно.307> - Метод [`most_common()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.most_common) требует только упорядочиваемости значений.308> - Для операций на месте, таких как `c[key] += 1`, тип значения должен поддерживать только сложение и вычитание. Так что дроби, числа с плавающей запятой и десятичные числа будут работать, и отрицательные значения поддерживаются. То же самое верно для [`update()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.update) и [`subtract()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.subtract), которые допускают отрицательные и нулевые значения как для входных, так и для выходных данных.309> - Методы мультимножеств предназначены только для случаев использования с положительными значениями. Входные данные могут быть отрицательными или нулевыми, но создаются только выходные данные с положительными значениями. Ограничений на тип нет, но тип значения должен поддерживать сложение, вычитание и сравнение.310> - Метод [`elements()`](https://python-all.ru/3.8/library/collections.html#collections.Counter.elements) требует целочисленных счётчиков. Он игнорирует нулевые и отрицательные счётчики.311312> **См. также**313>314> - [Класс Bag](https://python-all.ru/3.8/library/collections.html) в Smalltalk.315> - Статья в Википедии о [мультимножествах](https://python-all.ru/3.8/library/collections.html).316> - [Мультимножества в C++](https://python-all.ru/3.8/library/collections.html): учебное пособие с примерами.317> - О математических операциях над мультимножествами и их применении см. *Кнут, Дональд. Искусство программирования, том II, раздел 4.6.3, упражнение 19*.318> - Для перечисления всех различных мультимножеств заданного размера над заданным набором элементов см. [`itertools.combinations_with_replacement()`](https://python-all.ru/3.8/library/itertools.html#itertools.combinations_with_replacement):319>320> ```python321> map(Counter, combinations_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC322> ```323324## [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque) объекты325326#### `class collections.deque([iterable[, maxlen]])`327328Возвращает новый объект deque, инициализированный слева направо (с помощью [`append()`](https://python-all.ru/3.8/library/collections.html#collections.deque.append)) данными из *итерируемого объекта*. Если *итерируемый объект* не указан, новый deque пуст.329330Deques представляют собой обобщение стеков и очередей (название произносится «дэк» и является сокращением от «двусторонняя очередь»). Deques поддерживают потокобезопасные и эффективные по памяти операции добавления и извлечения элементов с любого из концов очереди с примерно одинаковой производительностью O(1) в обоих направлениях.331332Хотя объекты [`list`](https://python-all.ru/3.8/library/stdtypes.html#list) поддерживают аналогичные операции, они оптимизированы для быстрых операций фиксированной длины и влекут за собой затраты на перемещение памяти O(n) для операций `pop(0)` и `insert(0, v)`, которые изменяют как размер, так и положение базового представления данных.333334Если *maxlen* не указан или равен `None`, deques могут расти до произвольной длины. В противном случае deque ограничен заданной максимальной длиной. Как только deque ограниченной длины заполняется, при добавлении новых элементов соответствующее количество элементов отбрасывается с противоположного конца. Deque с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix. Они также полезны для отслеживания транзакций и других пулов данных, где интерес представляет только самая последняя активность.335336Объекты deque поддерживают следующие методы:337338#### `append(x)`339340Добавляет *x* в правую часть deque.341342#### `appendleft(x)`343344Добавляет *x* в левую часть deque.345346#### `clear()`347348Удаляет все элементы из deque, после чего его длина равна 0.349350#### `copy()`351352Создаёт поверхностную копию deque.353354Новое в версии 3.5.355356#### `count(x)`357358Подсчитывает количество элементов deque, равных *x*.359360Новое в версии 3.2.361362#### `extend(iterable)`363364Расширяет правую часть deque, добавляя элементы из итерируемого объекта.365366#### `extendleft(iterable)`367368Расширяет левую часть deque, добавляя элементы из *итерируемого объекта*. Обратите внимание: последовательное добавление слева приводит к обращению порядка элементов в итерируемом объекте.369370#### `index(x[, start[, stop]])`371372Возвращает позицию *x* в deque (начиная с индекса *start* и до индекса *stop*). Возвращает первое совпадение или возбуждает [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError), если не найдено.373374Новое в версии 3.5.375376#### `insert(i, x)`377378Вставляет *x* в deque на позицию *i*.379380Если вставка приведёт к тому, что ограниченный deque превысит *maxlen*, вызывается исключение [`IndexError`](https://python-all.ru/3.8/library/exceptions.html#IndexError).381382Новое в версии 3.5.383384#### `pop()`385386Удаляет и возвращает элемент из правой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/3.8/library/exceptions.html#IndexError).387388#### `popleft()`389390Удаляет и возвращает элемент из левой части deque. Если элемент отсутствует, вызывает исключение [`IndexError`](https://python-all.ru/3.8/library/exceptions.html#IndexError).391392#### `remove(value)`393394Удаляет первое вхождение *значения*. Если не найдено, вызывает исключение [`ValueError`](https://python-all.ru/3.8/library/exceptions.html#ValueError).395396#### `reverse()`397398Переворачивает элементы deque на месте и возвращает `None`.399400Новое в версии 3.2.401402#### `rotate(n=1)`403404Поворачивает deque на *n* шагов вправо. Если *n* отрицательное, поворачивает влево.405406Когда deque не пуст, поворот на один шаг вправо эквивалентен `d.appendleft(d.pop())`, а поворот на один шаг влево – `d.append(d.popleft())`.407408Объекты deque также предоставляют один атрибут только для чтения:409410#### `maxlen`411412Максимальный размер дека или `None`, если неограничен.413414Новое в версии 3.1.415416В дополнение к вышеперечисленному, deques поддерживают итерацию, сериализацию (pickling), `len(d)`, `reversed(d)`, `copy.copy(d)`, `copy.deepcopy(d)`, проверку принадлежности с помощью оператора [`in`](https://python-all.ru/3.8/reference/expressions.html#in) и обращения по индексу, например `d[0]` для доступа к первому элементу. Доступ по индексу выполняется за O(1) на обоих концах, но замедляется до O(n) в середине. Для быстрого произвольного доступа лучше использовать списки.417418Начиная с версии 3.5, деки поддерживают `__add__()`, `__mul__()` и `__imul__()`.419420Пример:421422```pycon423>>> from collections import deque424>>> d = deque('ghi') # создать новый deque с тремя элементами425>>> for elem in d: # обход элементов deque426... print(elem.upper())427G428H429I430431>>> d.append('j') # добавить новый элемент справа432>>> d.appendleft('f') # добавить новый элемент слева433>>> d # показать представление deque434deque(['f', 'g', 'h', 'i', 'j'])435436>>> d.pop() # вернуть и удалить правый элемент437'j'438>>> d.popleft() # вернуть и удалить левый элемент439'f'440>>> list(d) # вывести содержимое deque441['g', 'h', 'i']442>>> d[0] # посмотреть левый элемент443'g'444>>> d[-1] # посмотреть правый элемент445'i'446447>>> list(reversed(d)) # вывести содержимое deque в обратном порядке448['i', 'h', 'g']449>>> 'h' in d # поиск в deque450True451>>> d.extend('jkl') # добавить несколько элементов за раз452>>> d453deque(['g', 'h', 'i', 'j', 'k', 'l'])454>>> d.rotate(1) # поворот вправо455>>> d456deque(['l', 'g', 'h', 'i', 'j', 'k'])457>>> d.rotate(-1) # поворот влево458>>> d459deque(['g', 'h', 'i', 'j', 'k', 'l'])460461>>> deque(reversed(d)) # создать новую deque в обратном порядке462deque(['l', 'k', 'j', 'i', 'h', 'g'])463>>> d.clear() # очистить deque464>>> d.pop() # невозможно извлечь элемент из пустой deque465Traceback (most recent call last):466 File "<pyshell#6>", line 1, in -toplevel-467 d.pop()468IndexError: pop from an empty deque469470>>> d.extendleft('abc') # extendleft() меняет порядок ввода на обратный471>>> d472deque(['c', 'b', 'a'])473```474475### [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque) Рецепты476477В этом разделе рассматриваются различные подходы к работе с деками.478479Деки с ограниченной длиной предоставляют функциональность, аналогичную фильтру `tail` в Unix:480481```python482def tail(filename, n=10):483 'Return the last n lines of a file'484 with open(filename) as f:485 return deque(f, n)486```487488Другой подход к использованию деков заключается в поддержании последовательности недавно добавленных элементов путем добавления справа и извлечения слева:489490```python491def moving_average(iterable, n=3):492 # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0493 # http://en.wikipedia.org/wiki/Moving_average494 it = iter(iterable)495 d = deque(itertools.islice(it, n-1))496 d.appendleft(0)497 s = sum(d)498 for elem in it:499 s += elem - d.popleft()500 d.append(elem)501 yield s / n502```503504[Планировщик round-robin](https://python-all.ru/3.8/library/collections.html) можно реализовать с помощью входных итераторов, хранящихся в [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque). Значения выдаются из активного итератора в позиции ноль. Если этот итератор исчерпан, его можно удалить с помощью [`popleft()`](https://python-all.ru/3.8/library/collections.html#collections.deque.popleft); в противном случае его можно вернуть в конец с помощью метода [`rotate()`](https://python-all.ru/3.8/library/collections.html#collections.deque.rotate):505506```python507def roundrobin(*iterables):508 "roundrobin('ABC', 'D', 'EF') --> A D E B F C"509 iterators = deque(map(iter, iterables))510 while iterators:511 try:512 while True:513 yield next(iterators[0])514 iterators.rotate(-1)515 except StopIteration:516 # Удалить исчерпанный итератор.517 iterators.popleft()518```519520Метод [`rotate()`](https://python-all.ru/3.8/library/collections.html#collections.deque.rotate) позволяет реализовать [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque) срезы и удаление. Например, чистая реализация `del d[n]` на Python использует метод `rotate()` для позиционирования элементов, которые нужно извлечь:521522```python523def delete_nth(d, n):524 d.rotate(-n)525 d.popleft()526 d.rotate(n)527```528529To implement [`deque`](https://python-all.ru/3.8/library/collections.html#collections.deque) slicing, use a similar approach applying [`rotate()`](https://python-all.ru/3.8/library/collections.html#collections.deque.rotate) to bring a target element to the left side of the deque. Remove old entries with [`popleft()`](https://python-all.ru/3.8/library/collections.html#collections.deque.popleft), add new entries with [`extend()`](https://python-all.ru/3.8/library/collections.html#collections.deque.extend), and then reverse the rotation. With minor variations on that approach, it is easy to implement Forth style stack manipulations such as `dup`, `drop`, `swap`, `over`, `pick`, `rot`, and `roll`.530531## [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) объекты532533#### `class collections.defaultdict([default_factory[, ...]])`534535Возвращает новый объект, похожий на словарь. [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) является подклассом встроенного класса [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict). Он переопределяет один метод и добавляет одну изменяемую переменную экземпляра. Остальная функциональность такая же, как у класса [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), и здесь не описывается.536537Первый аргумент задает начальное значение для атрибута [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory); по умолчанию он равен `None`. Все остальные аргументы обрабатываются так же, как если бы они были переданы конструктору [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), включая именованные аргументы.538539[`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) объекты поддерживают следующий метод в дополнение к стандартным операциям [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict):540541#### `__missing__(key)`542543Если атрибут [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) равен `None`, возникает исключение [`KeyError`](https://python-all.ru/3.8/library/exceptions.html#KeyError) с аргументом *key*.544545Если [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) не равен `None`, он вызывается без аргументов для предоставления значения по умолчанию для заданного *key*; это значение вставляется в словарь для *key* и возвращается.546547Если вызов [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) вызывает исключение, это исключение распространяется без изменений.548549Этот метод вызывается методом [`__getitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__getitem__) класса [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), когда запрошенный ключ не найден; все, что он возвращает или возбуждает, затем возвращается или возбуждается методом [`__getitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__getitem__).550551Обратите внимание, что [`__missing__()`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.__missing__) *не* вызывается ни для каких операций, кроме [`__getitem__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__getitem__). Это означает, что `get()` будет, как обычные словари, возвращать `None` по умолчанию, а не использовать [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory).552553[`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) объекты поддерживают следующую переменную экземпляра:554555#### `default_factory`556557Этот атрибут используется методом [`__missing__()`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.__missing__); он инициализируется из первого аргумента конструктора, если он передан, или `None`, если не передан.558559### [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) Примеры560561Используя [`list`](https://python-all.ru/3.8/library/stdtypes.html#list) в качестве [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory), легко сгруппировать последовательность пар ключ-значение в словарь списков:562563```python564>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]565>>> d = defaultdict(list)566>>> for k, v in s:567... d[k].append(v)568...569>>> sorted(d.items())570[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]571```572573Когда ключ встречается впервые, его еще нет в отображении; поэтому запись автоматически создается с помощью функции [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory), которая возвращает пустой [`list`](https://python-all.ru/3.8/library/stdtypes.html#list). Затем операция `list.append()` присоединяет значение к новому списку. Когда ключи встречаются снова, поиск выполняется обычным образом (возвращается список для этого ключа), и операция `list.append()` добавляет еще одно значение в список. Этот метод проще и быстрее, чем эквивалентный метод с использованием [`dict.setdefault()`](https://python-all.ru/3.8/library/stdtypes.html#dict.setdefault):574575```python576>>> d = {}577>>> for k, v in s:578... d.setdefault(k, []).append(v)579...580>>> sorted(d.items())581[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]582```583584Установка [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) в [`int`](https://python-all.ru/3.8/library/functions.html#int) делает [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) удобным для подсчёта (как bag или мультимножество в других языках):585586```python587>>> s = 'mississippi'588>>> d = defaultdict(int)589>>> for k in s:590... d[k] += 1591...592>>> sorted(d.items())593[('i', 4), ('m', 1), ('p', 2), ('s', 4)]594```595596Когда буква встречается впервые, в отображении она отсутствует, поэтому функция [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) вызывает [`int()`](https://python-all.ru/3.8/library/functions.html#int) для получения нулевого значения по умолчанию. Затем операция инкремента наращивает счётчик для каждой буквы.597598Функция [`int()`](https://python-all.ru/3.8/library/functions.html#int), всегда возвращающая ноль, – это всего лишь частный случай константных функций. Более быстрый и гибкий способ создания константных функций – использовать лямбда-функцию, которая может возвращать любое константное значение (не только ноль):599600```python601>>> def constant_factory(value):602... return lambda: value603>>> d = defaultdict(constant_factory('<missing>'))604>>> d.update(name='John', action='ran')605>>> '%(name)s %(action)s to %(object)s' % d606'John ran to <missing>'607```608609Установка [`default_factory`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict.default_factory) в [`set`](https://python-all.ru/3.8/library/stdtypes.html#set) делает [`defaultdict`](https://python-all.ru/3.8/library/collections.html#collections.defaultdict) удобным для построения словаря множеств:610611```python612>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]613>>> d = defaultdict(set)614>>> for k, v in s:615... d[k].add(v)616...617>>> sorted(d.items())618[('blue', {2, 4}), ('red', {1, 3})]619```620621## [`namedtuple()`](https://python-all.ru/3.8/library/collections.html#collections.namedtuple) Фабричная функция для кортежей с именованными полями622623Именованные кортежи придают смысл каждой позиции в кортеже и позволяют писать более читаемый, самодокументируемый код. Их можно использовать везде, где используются обычные кортежи, и они добавляют возможность доступа к полям по имени, а не по индексу.624625#### `collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)`626627Возвращает новый подкласс кортежа с именем *typename*. Новый подкласс используется для создания объектов, подобных кортежам, поля которых доступны через атрибуты, а также поддерживают индексацию и итерацию. Экземпляры подкласса также имеют полезную docstring (с именем типа и именами полей) и полезный метод [`__repr__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__repr__), который выводит содержимое кортежа в формате `name=value`.628629Параметр *field\_names* представляет собой последовательность строк, например `['x', 'y']`. В качестве альтернативы *field\_names* может быть единой строкой, в которой имена полей разделены пробелами и/или запятыми, например `'x y'` или `'x, y'`.630631В качестве имени поля может использоваться любой допустимый идентификатор Python, кроме имён, начинающихся с подчёркивания. Допустимые идентификаторы состоят из букв, цифр и символов подчёркивания, но не начинаются с цифры или подчёркивания и не могут быть [`keyword`](https://python-all.ru/3.8/library/keyword.html#module-keyword), например *class*, *for*, *return*, *global*, *pass*, или *raise*.632633Если *rename* равен true, недопустимые имена полей автоматически заменяются позиционными именами. Например, `['abc', 'def', 'ghi', 'abc']` преобразуется в `['abc', '_1', 'ghi', '_3']`, устраняя ключевое слово `def` и дублирующееся имя поля `abc`.634635Параметр *defaults* может быть `None` или [итерируемым объектом](https://python-all.ru/3.8/glossary.html#term-iterable) значений по умолчанию. Поскольку поля со значением по умолчанию должны идти после полей без умолчания, *defaults* применяются к самым правым параметрам. Например, если имена полей `['x', 'y', 'z']`, а значения по умолчанию – `(1, 2)`, то `x` будет обязательным аргументом, `y` по умолчанию будет равно `1`, а `z` – `2`.636637Если определён *module*, атрибут `__module__` именованного кортежа устанавливается в это значение.638639Экземпляры именованных кортежей не имеют собственных словарей, поэтому они легковесны и потребляют не больше памяти, чем обычные кортежи.640641Изменено в версии 3.1: Добавлена поддержка *rename*.642643Изменено в версии 3.6: Параметры *verbose* и *rename* стали [только именованными аргументами](https://python-all.ru/3.8/glossary.html#keyword-only-parameter).644645Изменено в версии 3.6: Добавлен параметр *module*.646647Изменено в версии 3.7: Удалены параметр *verbose* и атрибут `_source`.648649Изменено в версии 3.7: Добавлены параметр *defaults* и атрибут `_field_defaults`.650651```pycon652>>> # Базовый пример653>>> Point = namedtuple('Point', ['x', 'y'])654>>> p = Point(11, y=22) # создать экземпляр с позиционными или именованными аргументами655>>> p[0] + p[1] # доступен по индексу, как обычный кортеж (11, 22)65633657>>> x, y = p # распаковывается как обычный кортеж658>>> x, y659(11, 22)660>>> p.x + p.y # поля также доступны по имени66133662>>> p # читаемое __repr__ в стиле name=value663Point(x=11, y=22)664```665666Именованные кортежи особенно полезны для присваивания имён полей кортежам результатов, возвращаемых модулями [`csv`](https://python-all.ru/3.8/library/csv.html#module-csv) или [`sqlite3`](https://python-all.ru/3.8/library/sqlite3.html#module-sqlite3):667668```python669EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')670671import csv672for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):673 print(emp.name, emp.title)674675import sqlite3676conn = sqlite3.connect('/companydata')677cursor = conn.cursor()678cursor.execute('SELECT name, age, title, department, paygrade FROM employees')679for emp in map(EmployeeRecord._make, cursor.fetchall()):680 print(emp.name, emp.title)681```682683В дополнение к методам, унаследованным от кортежей, именованные кортежи поддерживают три дополнительных метода и два атрибута. Чтобы избежать конфликтов с именами полей, имена методов и атрибутов начинаются с подчёркивания.684685#### `classmethod somenamedtuple._make(iterable)`686687Метод класса, который создаёт новый экземпляр из существующей последовательности или итерируемого объекта.688689```pycon690>>> t = [11, 22]691>>> Point._make(t)692Point(x=11, y=22)693```694695#### `somenamedtuple._asdict()`696697Возвращает новый [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), который отображает имена полей в соответствующие значения:698699```pycon700>>> p = Point(x=11, y=22)701>>> p._asdict()702{'x': 11, 'y': 22}703```704705Изменено в версии 3.1: Возвращает [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) вместо обычного [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict).706707Изменено в версии 3.8: Возвращает обычный [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict) вместо [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict). Начиная с Python 3.7, обычные словари гарантированно упорядочены. Если требуются дополнительные возможности [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict), рекомендуется преобразовать результат к нужному типу: `OrderedDict(nt._asdict())`.708709#### `somenamedtuple._replace(**kwargs)`710711Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями:712713```python714>>> p = Point(x=11, y=22)715>>> p._replace(x=33)716Point(x=33, y=22)717718>>> for partnum, record in inventory.items():719... inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())720```721722#### `somenamedtuple._fields`723724Кортеж строк с именами полей. Полезен для интроспекции и для создания новых типов именованных кортежей из существующих.725726```pycon727>>> p._fields # просмотреть имена полей728('x', 'y')729730>>> Color = namedtuple('Color', 'red green blue')731>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)732>>> Pixel(11, 22, 128, 255, 0)733Pixel(x=11, y=22, red=128, green=255, blue=0)734```735736#### `somenamedtuple._field_defaults`737738Словарь, отображающий имена полей в значения по умолчанию.739740```pycon741>>> Account = namedtuple('Account', ['type', 'balance'], defaults=[0])742>>> Account._field_defaults743{'balance': 0}744>>> Account('premium')745Account(type='premium', balance=0)746```747748Чтобы получить поле, имя которого хранится в строке, используйте функцию [`getattr()`](https://python-all.ru/3.8/library/functions.html#getattr) :749750```python751>>> getattr(p, 'x')75211753```754755Чтобы преобразовать словарь в именованный кортеж, используйте оператор двойной звёздочки (как описано в разделе [Распаковка списков аргументов](https://python-all.ru/3.8/tutorial/controlflow.html#tut-unpacking-arguments)):756757```python758>>> d = {'x': 11, 'y': 22}759>>> Point(**d)760Point(x=11, y=22)761```762763Поскольку именованный кортеж – это обычный класс Python, легко добавить или изменить функциональность с помощью подкласса. Вот как добавить вычисляемое поле и формат печати с фиксированной шириной:764765```pycon766>>> class Point(namedtuple('Point', ['x', 'y'])):767... __slots__ = ()768... @property769... def hypot(self):770... return (self.x ** 2 + self.y ** 2) ** 0.5771... def __str__(self):772... return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)773774>>> for p in Point(3, 4), Point(14, 5/7):775... print(p)776Point: x= 3.000 y= 4.000 hypot= 5.000777Point: x=14.000 y= 0.714 hypot=14.018778```779780Подкласс, показанный выше, устанавливает `__slots__` в пустой кортеж. Это помогает снизить требования к памяти, предотвращая создание словарей экземпляров.781782Наследование не подходит для добавления новых хранимых полей. Вместо этого просто создайте новый тип именованного кортежа из атрибута [`_fields`](https://python-all.ru/3.8/library/collections.html#collections.somenamedtuple._fields):783784```python785>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))786```787788Докстринги можно настроить, напрямую присваивая значения полям `__doc__` :789790```python791>>> Book = namedtuple('Book', ['id', 'title', 'authors'])792>>> Book.__doc__ += ': Hardcover book in active collection'793>>> Book.id.__doc__ = '13-digit ISBN'794>>> Book.title.__doc__ = 'Title of first printing'795>>> Book.authors.__doc__ = 'List of authors sorted by last name'796```797798Изменено в версии 3.5: Докстринги свойств стали доступны для записи.799800> **См. также**801>802> - Смотрите [`typing.NamedTuple`](https://python-all.ru/3.8/library/typing.html#typing.NamedTuple) для способа добавления подсказок типов для именованных кортежей. Он также предоставляет элегантную запись с использованием ключевого слова [`class`](https://python-all.ru/3.8/reference/compound_stmts.html#class) :803>804> ```python805> class Component(NamedTuple):806> part_number: int807> weight: float808> description: Optional[str] = None809> ```810> - Смотрите [`types.SimpleNamespace()`](https://python-all.ru/3.8/library/types.html#types.SimpleNamespace) для изменяемого пространства имён на основе словаря вместо кортежа.811> - Модуль [`dataclasses`](https://python-all.ru/3.8/library/dataclasses.html#module-dataclasses) предоставляет декоратор и функции для автоматического добавления сгенерированных специальных методов в пользовательские классы.812813## [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) объекты814815Упорядоченные словари похожи на обычные словари, но имеют некоторые дополнительные возможности, связанные с операциями упорядочивания. Они стали менее важны, поскольку встроенный класс [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict) получил возможность запоминать порядок вставки (это новое поведение стало гарантированным в Python 3.7).816817Некоторые отличия от [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict) всё ещё остаются:818819- Обычный [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict) был спроектирован для очень хорошей работы с операциями отображения. Отслеживание порядка вставки было второстепенным.820- [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) был спроектирован для хорошей работы с операциями переупорядочивания. Эффективность использования памяти, скорость итерации и производительность операций обновления были второстепенными.821- С алгоритмической точки зрения [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) может обрабатывать частые переупорядочения эффективнее, чем [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict). Это делает его пригодным для отслеживания недавних обращений (например, в [LRU-кэше](https://python-all.ru/3.8/library/collections.html)).822- Операция равенства для [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) проверяет соответствие порядка.823- Метод `popitem()` у [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) имеет другую сигнатуру. Он принимает необязательный аргумент для указания того, какой элемент извлекается.824- У [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) есть метод `move_to_end()` для эффективного перемещения элемента в конец или начало.825- До Python 3.8 у [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict) отсутствовал метод [`__reversed__()`](https://python-all.ru/3.8/reference/datamodel.html#object.__reversed__).826827#### `class collections.OrderedDict([items])`828829Возвращает экземпляр подкласса [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict), который содержит методы для перестановки порядка словаря.830831Новое в версии 3.1.832833#### `popitem(last=True)`834835Метод [`popitem()`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict.popitem) для упорядоченных словарей возвращает и удаляет пару (key, value). Пары возвращаются в порядке LIFO, если *last* истинно, или в порядке FIFO, если ложно.836837#### `move_to_end(key, last=True)`838839Перемещает существующий *ключ* в начало или конец упорядоченного словаря. Элемент перемещается в конец, если *last* истинно (по умолчанию), или в начало, если *last* ложно. Вызывает [`KeyError`](https://python-all.ru/3.8/library/exceptions.html#KeyError), если *ключ* не существует:840841```python842>>> d = OrderedDict.fromkeys('abcde')843>>> d.move_to_end('b')844>>> ''.join(d.keys())845'acdeb'846>>> d.move_to_end('b', last=False)847>>> ''.join(d.keys())848'bacde'849```850851Новое в версии 3.2.852853Помимо обычных методов отображений, упорядоченные словари также поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.8/library/functions.html#reversed).854855Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) чувствительны к порядку и реализованы как `list(od1.items())==list(od2.items())`. Проверки равенства между объектами [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) и другими объектами [`Mapping`](https://python-all.ru/3.8/library/collections.abc.html#collections.abc.Mapping) нечувствительны к порядку, как обычные словари. Это позволяет подставлять объекты [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) в любом месте, где используется обычный словарь.856857Изменено в версии 3.5: Представления [представления](https://python-all.ru/3.8/glossary.html#term-dictionary-view) элементов, ключей и значений объекта [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) теперь поддерживают обратную итерацию с помощью [`reversed()`](https://python-all.ru/3.8/library/functions.html#reversed).858859Изменено в версии 3.6: С принятием [**PEP 468**](https://python-all.ru/3.8/library/collections.html) порядок сохраняется для именованных аргументов, передаваемых конструктору [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) и его методу `update()` .860861### [`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) Примеры и рецепты862863It is straightforward to create an ordered dictionary variant that remembers the order the keys were *last* inserted. If a new entry overwrites an existing entry, the original insertion position is changed and moved to the end:864865```python866class LastUpdatedOrderedDict(OrderedDict):867 'Store items in the order the keys were last added'868869 def __setitem__(self, key, value):870 super().__setitem__(key, value)871 self.move_to_end(key)872```873874[`OrderedDict`](https://python-all.ru/3.8/library/collections.html#collections.OrderedDict) также был бы полезен для реализации вариантов [`functools.lru_cache()`](https://python-all.ru/3.8/library/functools.html#functools.lru_cache):875876```python877class LRU(OrderedDict):878 'Limit size, evicting the least recently looked-up key when full'879880 def __init__(self, maxsize=128, /, *args, **kwds):881 self.maxsize = maxsize882 super().__init__(*args, **kwds)883884 def __getitem__(self, key):885 value = super().__getitem__(key)886 self.move_to_end(key)887 return value888889 def __setitem__(self, key, value):890 if key in self:891 self.move_to_end(key)892 super().__setitem__(key, value)893 if len(self) > self.maxsize:894 oldest = next(iter(self))895 del self[oldest]896```897898## [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict) объекты899900Класс [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict) действует как обёртка вокруг объектов-словарей. Необходимость в этом классе отчасти утрачена из-за возможности наследовать напрямую от [`dict`](https://python-all.ru/3.8/library/stdtypes.html#dict); однако с ним может быть проще работать, поскольку базовый словарь доступен как атрибут.901902#### `class collections.UserDict([initialdata])`903904Класс, имитирующий словарь. Содержимое экземпляра хранится в обычном словаре, доступном через атрибут [`data`](https://python-all.ru/3.8/library/collections.html#collections.UserDict.data) экземпляров [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict). Если указан параметр *initialdata*, то [`data`](https://python-all.ru/3.8/library/collections.html#collections.UserDict.data) инициализируется его содержимым; обратите внимание, что ссылка на *initialdata* не сохраняется, что позволяет использовать её для других целей.905906В дополнение к поддержке методов и операций отображений, экземпляры [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict) предоставляют следующий атрибут:907908#### `data`909910Реальный словарь, используемый для хранения содержимого класса [`UserDict`](https://python-all.ru/3.8/library/collections.html#collections.UserDict) .911912## [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList) объекты913914Этот класс действует как обёртка вокруг объектов-списков. Это полезный базовый класс для собственных классов, подобных спискам, которые могут наследовать от них и переопределять существующие методы или добавлять новые. Таким образом, можно добавлять новое поведение к спискам.915916Необходимость в этом классе отчасти утрачена из-за возможности наследовать напрямую от [`list`](https://python-all.ru/3.8/library/stdtypes.html#list); однако с этим классом может быть проще работать, поскольку базовый список доступен как атрибут.917918#### `class collections.UserList([list])`919920Класс, который имитирует список. Содержимое экземпляра хранится в обычном списке, доступном через атрибут [`data`](https://python-all.ru/3.8/library/collections.html#collections.UserList.data) экземпляров [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList). Содержимое экземпляра изначально устанавливается как копия *list*, по умолчанию – пустой список `[]`. *list* может быть любым итерируемым объектом, например настоящим списком Python или объектом [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList).921922В дополнение к поддержке методов и операций изменяемых последовательностей, экземпляры [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList) предоставляют следующий атрибут:923924#### `data`925926Настоящий объект [`list`](https://python-all.ru/3.8/library/stdtypes.html#list), используемый для хранения содержимого класса [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList).927928**Требования к подклассам:** Ожидается, что подклассы [`UserList`](https://python-all.ru/3.8/library/collections.html#collections.UserList) предоставляют конструктор, который можно вызывать без аргументов или с одним аргументом. Операции со списками, возвращающие новую последовательность, пытаются создать экземпляр фактического класса реализации. Для этого предполагается, что конструктор можно вызвать с одним параметром – объектом-последовательностью, используемым как источник данных.929930Если производный класс не желает соблюдать это требование, все специальные методы, поддерживаемые этим классом, должны быть переопределены; обратитесь к исходному коду за информацией о методах, которые необходимо предоставить в этом случае.931932## [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString) объекты933934Класс [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString) выступает в качестве обёртки для строковых объектов. Необходимость в этом классе частично отпала благодаря возможности создания подклассов непосредственно от [`str`](https://python-all.ru/3.8/library/stdtypes.html#str); однако с этим классом может быть проще работать, так как базовая строка доступна в виде атрибута.935936#### `class collections.UserString(seq)`937938Класс, который имитирует строковый объект. Содержимое экземпляра хранится в обычном строковом объекте, доступ к которому осуществляется через атрибут [`data`](https://python-all.ru/3.8/library/collections.html#collections.UserString.data) экземпляров [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString). Содержимое экземпляра изначально устанавливается в копию *seq*. Аргумент *seq* может быть любым объектом, который можно преобразовать в строку с помощью встроенной функции [`str()`](https://python-all.ru/3.8/library/stdtypes.html#str).939940В дополнение к поддержке методов и операций со строками, экземпляры [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString) предоставляют следующий атрибут:941942#### `data`943944Настоящий объект [`str`](https://python-all.ru/3.8/library/stdtypes.html#str), используемый для хранения содержимого класса [`UserString`](https://python-all.ru/3.8/library/collections.html#collections.UserString).945946Изменено в версии 3.5: Новые методы `__getnewargs__`, `__rmod__`, `casefold`, `format_map`, `isprintable` и `maketrans`.947