Как обойти несколько источников подряд через itertools.chain в Python

Как обойти несколько источников подряд через itertools.chain в Python
Содержание статьи

itertools.chain последовательно выдаёт элементы нескольких источников. Сначала он заканчивает первый, затем переходит к следующему. Разберём на Mentoring.digital, когда такой обход удобнее создания общего списка и какие ограничения важно учитывать.

Объединяем обход двух источников

from itertools import chain

first = [10, 20]
second = (n for n in [30, 40])
items = chain(first, second)

print(next(items))  # 10
print(list(items))  # [20, 30, 40]
print(list(items))  # []

Создание chain не копирует все элементы в один список. Элементы извлекаются по мере обхода. Однако вызов list(items) уже собирает оставшийся результат в памяти. В примере число 10 прочитано отдельно и в этот список не попадает.

Сам объект items является итератором: после полного обхода он исчерпан. Повторный вызов list не начинает чтение заново. Если нужен повторный проход, заранее решите, можно ли повторно создать источники или требуется сохранить результат.

Если источники сами приходят потоком

from itertools import chain

groups = (part for part in [[1, 2], [], [3]])
items = chain.from_iterable(groups)

print(list(items))  # [1, 2, 3]

from_iterable принимает один источник, элементы которого тоже можно обходить. Пустая внутренняя группа ничего не добавляет. Внешний генератор потребляется постепенно. Это отличается от chain(*groups): распаковка аргументов должна сначала получить все группы, чтобы выполнить вызов функции.

Что этот приём не делает

Обход не сортирует данные, не удаляет повторы и не чередует элементы источников. Если первый источник бесконечный, до второго очередь не дойдёт. Строка тоже является итерируемым объектом, поэтому её элементы будут отдельными символами. Вложенность снимается только на один уровень.

Изменяемые объекты не превращаются в независимые копии. Если это важно для дальнейшей обработки, копирование следует проектировать отдельно. Задача chain состоит в организации обхода.

Практическое задание

Подготовьте три источника событий: список, пустой список и генератор. Прочитайте один элемент, затем остаток. Объясните порядок и результат повторного прохода. После этого замените последний источник строкой и проверьте, подходит ли такое поведение вашей задаче.

Работу с итераторами можно включить в практическое обучение Python. Разобрать способ обработки данных в своём проекте поможет наставник по Python.

Похожие статьи по данной теме