Статьи

Учебные материалы по языку Python — от основ до продвинутых тем

Модуль collections

Страница 33 из 34 · 2026-10-26 · 5 мин чтения

Обзор

Модуль collections содержит специализированные контейнеры, дополняющие встроенные list, dict, set и tuple:

КлассНазначение
dequeДвусторонняя очередь
CounterПодсчёт хешируемых объектов
defaultdictСловарь со значением по умолчанию
OrderedDictСловарь с операциями над порядком
ChainMapОбъединённое представление нескольких словарей
namedtupleКортеж с именованными полями
UserDict, UserList, UserStringБазовые классы для расширения встроенных типов

deque

Двусторонняя очередь с быстрыми операциями на обоих концах (O(1)):

from collections import dequed = deque([1, 2, 3])d.append(4)d.appendleft(0)print(d)print(d.pop())print(d.popleft())

Методы deque

МетодОписание
append(x), appendleft(x)Добавление справа и слева
pop(), popleft()Извлечение справа и слева
extend(iterable), extendleft(iterable)Добавление нескольких элементов
rotate(n)Циклический сдвиг, положительное n — вправо
clear()Очистка
copy()Поверхностная копия
count(x), index(x), insert(i, x), remove(x), reverse()Как у списка
maxlenМаксимальная длина или None
d = deque([1, 2, 3, 4, 5])d.rotate(2)print(d)d.rotate(-1)print(d)

Ограничение длины

При заданном maxlen старые элементы вытесняются:

last3 = deque(maxlen=3)for i in range(6):    last3.append(i)print(last3)

Результат: deque([3, 4, 5], maxlen=3).

Индексация в середине deque медленная — O(n). Для произвольного доступа используйте список.

Очередь для обхода в ширину

from collections import dequegraph = {"a": ["b", "c"], "b": ["d"], "c": ["d"], "d": []}def bfs(start):    seen = {start}    queue = deque([start])    order = []    while queue:        node = queue.popleft()        order.append(node)        for nxt in graph[node]:            if nxt not in seen:                seen.add(nxt)                queue.append(nxt)    return orderprint(bfs("a"))

Counter

Подкласс dict, считающий вхождения:

from collections import Counterc = Counter("abracadabra")print(c)print(c["a"])print(c["z"])print(c.most_common(2))print(list(c.elements())[:3])

Методы Counter

МетодОписание
most_common([n])Список пар (элемент, число) по убыванию
elements()Итератор элементов с повторами
update(iterable_or_mapping)Добавляет счётчики
subtract(iterable_or_mapping)Вычитает счётчики
total()Сумма счётчиков (Python 3.10+)

Арифметика

a = Counter(x=3, y=1)b = Counter(x=1, y=2, z=4)print(a + b)print(a - b)print(a & b)print(a | b)

Сложение и вычитание отбрасывают нулевые и отрицательные значения.

words = "the quick brown fox jumps over the lazy dog the end".split()print(Counter(words).most_common(1))

defaultdict

Словарь, создающий значение при обращении к отсутствующему ключу:

from collections import defaultdictdd = defaultdict(list)dd["a"].append(1)dd["a"].append(2)dd["b"].append(3)print(dict(dd))counts = defaultdict(int)for ch in "hello":    counts[ch] += 1print(dict(counts))tree = lambda: defaultdict(tree)root = tree()root["a"]["b"]["c"] = 1

default_factory — вызываемый объект без аргументов: list, int, set, dict или любая функция. Проверка key in dd не создаёт ключ, а dd[key] создаёт.

OrderedDict

С Python 3.7 обычный dict сохраняет порядок, но OrderedDict по-прежнему имеет дополнительные возможности:

from collections import OrderedDictod = OrderedDict([("a", 1), ("b", 2), ("c", 3)])od.move_to_end("a")print(list(od))od.move_to_end("c", last=False)print(list(od))print(od.popitem(last=False))
МетодОписание
move_to_end(key, last=True)Перемещает ключ в конец или начало
popitem(last=True)Удаляет с конца или начала

Сравнение двух OrderedDict учитывает порядок, а обычных словарей — нет.

LRU-кеш

from collections import OrderedDictclass LRU:    def __init__(self, capacity):        self.capacity = capacity        self.data = OrderedDict()    def get(self, key):        if key not in self.data:            return None        self.data.move_to_end(key)        return self.data[key]    def put(self, key, value):        self.data[key] = value        self.data.move_to_end(key)        if len(self.data) > self.capacity:            self.data.popitem(last=False)

ChainMap

Объединяет несколько словарей в одно представление без копирования. Поиск идёт слева направо:

from collections import ChainMapdefaults = {"color": "red", "user": "guest"}env = {"user": "admin"}cli = {"color": "blue"}settings = ChainMap(cli, env, defaults)print(settings["color"])print(settings["user"])settings["new"] = 1print(cli)child = settings.new_child({"debug": True})print(child["debug"], child["color"])print(settings.maps)

Запись и удаление затрагивают только первый словарь.

namedtuple

from collections import namedtuplePoint = namedtuple("Point", "x y")Person = namedtuple("Person", ["name", "age"], defaults=[0])p = Point(1, 2)print(p, p.x, p._asdict())print(Person("Anna"))

Подробнее — в главе про tuple.

UserDict, UserList, UserString

Обёртки для безопасного наследования. Прямое наследование от dict или list часто не работает так, как ожидается, потому что встроенные методы не вызывают переопределённые:

class BadDict(dict):    def __setitem__(self, key, value):        super().__setitem__(key, value * 2)bad = BadDict(a=1)bad.update(b=2)print(bad)

Результат: {'a': 2, 'b': 2} — update обошёл переопределённый метод. С UserDict он будет вызван:

from collections import UserDictclass GoodDict(UserDict):    def __setitem__(self, key, value):        super().__setitem__(key, value * 2)good = GoodDict(a=1)good.update(b=2)print(good)

Результат: {'a': 2, 'b': 4}.

Абстрактные базовые классы

collections.abc содержит ABC для проверки интерфейсов:

КлассТребуемые методы
Iterable__iter__
Iterator__iter__, __next__
Sized__len__
Container__contains__
Collection__len__, __iter__, __contains__
Sequence__getitem__, __len__
MutableSequenceплюс __setitem__, __delitem__, insert
Mapping__getitem__, __iter__, __len__
MutableMappingплюс __setitem__, __delitem__
Set, MutableSetоперации множеств
Callable__call__
Hashable__hash__
Generator, Awaitable, CoroutineПротоколы генераторов и корутин
from collections.abc import Iterable, Mapping, Sequenceprint(isinstance([1], Sequence))print(isinstance({}, Mapping))print(isinstance("abc", Iterable))print(isinstance({1}, Sequence))

Задания

  1. Реализуйте скользящее среднее по последним n значениям через deque(maxlen=n).
  2. Найдите топ-5 самых частых слов в тексте через Counter.
  3. Постройте настройки приложения из трёх уровней приоритета с помощью ChainMap.