Открыв collections, сложно вернуться к обычным спискам и словарям.

Вступление

Модуль collections в Python — это сокровищница для работы с данными. Он расширяет стандартные структуры Python, предлагая более продвинутые и удобные решения для обработки данных. В этой статье мы рассмотрим важные структуры, доступные в модуле, и узнаем, как они могут упрощать жизнь разработчика.


1. Counter

Что это?

Counter — это класс для учета количества вхождений элементов в последовательности. Он особенно полезен для анализа данных, таких как статистика слов в тексте.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

iterable

Исходные данные (список, строка и т.д.)

iterable

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

elements()

-

iterator

Возвращает элементы по очереди.

most_common(n)

n — кол-во эл.

list

Самые частые элементы.

subtract(other)

iterable/dict

None

Вычитает элементы.

Пример кода

from collections import Counter

text = "apple orange banana apple orange apple"
counter = Counter(text.split())
print(counter.most_common(2))
# [('apple', 3), ('orange', 2)]

Описание примера: В этом примере мы считаем количество каждого слова в строке и выводим два самых популярных.

Преимущества и ограничения

Преимущества:

  • Простота использования для подсчёта.

  • Подходит для анализа текста и данных.

Ограничения:

  • Неэффективен при работе с большими наборами данных.

  • Подходит только для однотипных объектов.


2. defaultdict

Что это?

defaultdict — это словарь, который автоматически задаёт значение по умолчанию для новых ключей. Полезен для избежания ошибок KeyError.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

default_factory

Функция для создания значения по умолчанию

callable

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

default_factory

-

callable

Устанавливает функцию по умолчанию.

get(key[, default])

Ключ, значение по умолчанию

Значение или default

Получить значение по ключу.

Пример кода

from collections import defaultdict

def_dict = defaultdict(int)
def_dict['apple'] += 1
print(def_dict['apple'])  # 1
print(def_dict['banana']) # 0

Описание примера: Пример показывает, как defaultdict автоматически задаёт значение по умолчанию (в данном случае 0) для отсутствующего ключа.

Преимущества и ограничения

Преимущества:

  • Упрощает обработку отсутствующих ключей.

  • Сокращает объем кода.

Ограничения:

  • Могут создаваться ненужные ключи, что увеличивает потребление памяти.


3. deque

Что это?

deque (double-ended queue) — это двусторонняя очередь с быстрой вставкой и удалением с обоих концов. Полезна для очередей, стеков и ротации данных.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

iterable

Исходные данные

iterable

None

maxlen

Максимальная длина очереди

int

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

append(x)

Элемент x

None

Добавить элемент в конец.

appendleft(x)

Элемент x

None

Добавить элемент в начало.

pop()

-

Элемент

Удалить и вернуть последний элемент.

popleft()

-

Элемент

Удалить и вернуть первый элемент.

Пример кода

from collections import deque

dq = deque([1, 2, 3], maxlen=5)
dq.append(4)
dq.appendleft(0)
print(dq)  # deque([0, 1, 2, 3, 4])

Описание примера: В примере показано добавление элементов в начало и конец двусторонней очереди с заданной максимальной длиной.

Преимущества и ограничения

Преимущества:

  • Быстрые операции вставки и удаления.

  • Поддержка ограниченной длины очереди.

Ограничения:

  • Линейный доступ к элементам медленнее, чем у списка.


4. namedtuple

Что это?

namedtuple — это кортеж с именованными полями. Упрощает доступ к элементам по именам вместо индексов.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

typename

Имя типа

str

-

field_names

Имена полей

list/str

-

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

_fields

-

tuple

Список полей.

_replace()

Поля со значениями

namedtuple

Создать копию с изменениями.

Пример кода

from collections import namedtuple

Point = namedtuple('Point', 'x y')
p = Point(10, 20)
print(p.x, p.y)  # 10 20

Описание примера: Пример демонстрирует, как с помощью namedtuple можно получить доступ к элементам по их именам.

Преимущества и ограничения

Преимущества:

  • Удобство работы с неизменяемыми структурами.

  • Улучшение читаемости кода.

Ограничения:

  • Невозможность изменения значений.


5. OrderedDict

Что это?

OrderedDict — это словарь, который сохраняет порядок добавления элементов. Полезен, когда порядок важен, например, при создании JSON или в аналитике данных.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

items

Итерируемая последовательность пар

iterable

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

move_to_end(key)

Ключ, где обновить порядок

None

Переместить элемент в конец/начало.

popitem(last=True)

Последний или первый элемент

tuple

Удалить элемент.

Пример кода

from collections import OrderedDict

od = OrderedDict()
od['apple'] = 1
od['banana'] = 2
od['cherry'] = 3
print(od)  # OrderedDict([('apple', 1), ('banana', 2), ('cherry', 3)])

Описание примера: Порядок добавления элементов в OrderedDict сохраняется, что полезно для предсказуемости.

Преимущества и ограничения

Преимущества:

  • Поддержка порядка элементов.

  • Полезно для сериализации.

Ограничения:

  • Более высокая память и время работы по сравнению с обычным словарём.


6. ChainMap

Что это?

ChainMap — это структура для объединения нескольких словарей в один. Полезна при работе с несколькими уровнями конфигураций.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

*maps

Списки словарей

list

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

new_child()

Дополнительный словарь

ChainMap

Добавить уровень.

parents

-

ChainMap

Вернуть родительские уровни.

Пример кода

from collections import ChainMap

defaults = {'theme': 'light', 'version': 1}
user_settings = {'theme': 'dark'}
settings = ChainMap(user_settings, defaults)
print(settings['theme'])  # dark

Описание примера: В этом примере объединяются два словаря, причём приоритет отдаётся первому.

Преимущества и ограничения

Преимущества:

  • Упрощение работы с несколькими конфигурациями.

  • Нет необходимости копировать данные.

Ограничения:

  • Только чтение объединенных данных.

  • Производительность ниже, чем у обычных словарей.


7. UserDict

Что это?

UserDict — это класс-обертка вокруг стандартного словаря, позволяющий переопределять поведение словаря. Удобен для наследования.

Как работает?

UserDict фактически является Python-объектом, который хранит данные в атрибуте data. Это позволяет изолировать пользовательские изменения от стандартной реализации словаря. Вы можете переопределить методы, такие как __setitem__ или __getitem__, для добавления специфического поведения.

Пример кода

from collections import UserDict

class MyDict(UserDict):
    def __setitem__(self, key, value):
        super().__setitem__(key, value.upper())

md = MyDict()
md['key'] = 'value'
print(md['key'])  # VALUE

Описание примера: Класс MyDict изменяет значение при добавлении в словарь, преобразуя его в верхний регистр.

Преимущества и ограничения

Преимущества:

  • Простота кастомизации.

  • Изоляция пользовательского поведения.

Ограничения:

  • Более медленная работа по сравнению с обычным словарём.


8. UserList

Что это?

UserList — это класс-обертка для списка, который позволяет изменять его поведение через наследование.

Как работает?

Класс UserList сохраняет внутренний список в атрибуте data. Это дает возможность модифицировать методы работы со списком, добавляя дополнительное поведение, без риска изменения базовой реализации списка.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

iterable

Итерируемая последовательность

iterable

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

append(x)

Элемент x

None

Добавить элемент в список.

remove(x)

Элемент x

None

Удалить первый найденный элемент.

pop([i])

Индекс i (необязательный)

Элемент

Удалить и вернуть элемент по индексу.

Пример кода

from collections import UserList

class MyList(UserList):
    def append(self, item):
        super().append(item * 2)

ml = MyList([1, 2])
ml.append(3)
print(ml)  # [1, 2, 6]

Описание примера: Метод append в данном примере автоматически удваивает добавляемые значения.

Преимущества и ограничения

Преимущества:

  • Простота расширения стандартного поведения списка.

  • Возможность полной кастомизации методов.

Ограничения:

  • Производительность ниже, чем у стандартного списка.

  • Требует дополнительной памяти на обертку.


9. UserString

Что это?

UserString — это класс-обертка для строк, который позволяет расширять или изменять поведение стандартных строк через наследование.

Как работает?

Класс UserString сохраняет строку в атрибуте data. Это позволяет изменять методы работы со строками, при этом не нарушая стандартное поведение базового класса.

Аргументы конструктора

Аргумент

Описание

Тип

По умолчанию

string

Исходная строка

str

None

Ключевые методы

Метод

Аргументы

Возвращаемое значение

Цель

__add__(s2)

Строка s2

UserString

Конкатенация строк.

__getitem__(i)

Индекс i

str

Получить символ по индексу.

lower()

-

UserString

Преобразовать строку к нижнему регистру.

Пример кода

from collections import UserString

class MyString(UserString):
    def append_exclamation(self):
        self.data += '!'

ms = MyString("Hello")
ms.append_exclamation()
print(ms)  # Hello!

Описание примера: Метод append_exclamation добавляет восклицательный знак к строке.

Преимущества и ограничения

Преимущества:

  • Удобный способ расширения поведения строк.

  • Сохраняет привычные методы строк Python.

Ограничения:

  • Производительность ниже, чем у стандартной строки.

  • Не подходит для операций, требующих высокой скорости.


Полезные ссылки

Официальная документация Python по модулю collections.
Руководство на Real Python: Python's collections: A Buffet of Specialized Data Types.


Заключение

Когда нужно решать задачи, стандартные инструменты Python хороши. Но collections даёт вам то, что помогает не просто "решать", а решать красиво, с минимумом усилий и без лишнего кода. Это как работать с хорошими инструментами: результат тот же, но процесс приятнее.

Подумайте о том, сколько кода можно сэкономить. А на сэкономленное время можно выпить кофе. Или два.

Комментарии (1)