Обход списка в Python по два элемента: эффективные способы
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Если перед нами стоит задача циклического обхода списка с шагом через два элемента, можно воспользоваться следующим кодом, использующим цикл for, функцию range и с шагом 2:
my_list = [1, 2, 3, 4, 5, 6]
for i in range(0, len(my_list), 2):
pair = my_list[i:i+2]
print(tuple(pair))
В результате выполнения данного кода выводом будут кортежи: (1, 2)
, (3, 4)
, (5, 6)
. Данный код работает безошибочно даже в случае списка с нечетной длиной.
Оптимизация производительности в Python 2 благодаря xrange
Если вы продолжаете работать с Python 2, xrange
представляет собой отличную альтернативу. Эта функция формирует объект xrange
, помогая оптимизировать использование памяти в процессе выполнения цикла:
for i in xrange(0, len(my_list), 2):
print(my_list[i:i+2])
Рецепт от мастера: Использование срезов списка
Выражения-срезы позволяют изящно "разделить" данные:
for pair in my_list[::2]:
print(pair)
Такой подход позволяет отбирать каждый второй элемент, однако не группирует их в пары.
Формирование пар с помощью функции Zip
Функция zip
умеет попарно соединять элементы, даже если они на первый взгляд несовместимы:
for left_sock, right_sock in zip(my_list[::2], my_list[1::2]):
print(left_sock, right_sock)
itertools для продвинутого формирования пар
itertools
— это эффективный инструмент для работы с парами:
from itertools import izip
for a, b in izip(*[iter(my_list)]*2):
print(a, b)
Благодаря функции izip
формирование пар возможно даже в кажущихся на первый взгляд неподходящих случаях.
Удобство использования итерируемых объектов
range
и xrange
создают итерируемые объекты, которые не формируют списки. Это весьма полезно при работе с большими последовательностями данных, когда важно эффективное использование памяти.
Ручная работа с индексами для тонкого контроля
Вам также доступна возможность взять инициативу в свои руки и непосредственно управлять циклом while:
i = 0
while i < len(my_list) – 1:
print(my_list[i], my_list[i+1])
i += 2
Рабочий процесс со списками различной длины
Функция zip_longest
из модуля itertools
отлично поможет вам формировать пары, когда списки имеют разную длину. Это решение идеально подходит для Python 3.
Визуализация: Вращение шестерёнок
Циклическое прохождение по списку можно представить как рабочую конвейерную ленту, на которой перемещаются предметы, подлежащие обработке попарно. Каждая пара представляет собой отдельную шестерёнку в общем механизме.
Список до начала: [🔧, 🔩, 🛠, 🧰, ⚙️, 🗜️]
1-й проход: [👷♂️🔧, 👷♂️🔩], [🛠, 🧰], [⚙️, 🗜️]
2-й проход: [🔧, 🔩], [👷♂️🛠, 👷♂️🧰], [⚙️, 🗜️]
3-й проход: [🔧, 🔩], [🛠, 🧰], [👷♂️⚙️, 👷♂️🗜️]
👷♂️ Рабочий движется по ленте, обрабатывает пару предметов за один проход.
Можно представить, что список 'tools' — это ваш список предметов, а каждый проход цикла — это шаг рабочего по конвейеру.
Тонкая настройка производительности и использования памяти
При выборе метода следует учитывать требования к производительности и эффективности использования памяти. Например, функции range()
и xrange()
прекрасно подойдут для итераций, не требующих создания списков индексов.
Ручное управление циклами для специфических случаев
Цикл while предоставляет широкие возможности для гибкого управления индексами и позволяет учесть особенности обработки списков с нечетным числом элементов или исключительными ситуациями внутри цикла.
Grouper: Универсальное решение
Функция grouper
из модуля itertools
предназначена для группировки элементов по заданному размеру:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
Это универсальный инструмент, облегчающий чтение кода.
Баланс между простотой и эффективностью
Python отдает предпочтение лаконичности и выразительности. Срезы списков прекрасны для простых случаев, но когда детали усложняются, не стоит бояться рассматривать и другие альтернативы.
Полезные материалы
- Циклический обход как у профи | Нед Батчелдер – подробное руководство по циклической обработке данных.
- itertools — Функции для создания итераторов для эффективного циклического прохождения — Документация Python 3.12.2 – разъяснение использования модуля
itertools
. - python – Формирования нового списка из каждого N-го элемента исходного списка – Stack Overflow — варианты решений для создания списка из каждого N-го элемента.
- Python enumerate(): Упрощение циклов с использованием счётчиков – Real Python – применение функции
enumerate()
для обозначения этапов в цикле. - Цикл for – Python Wiki – обзор различных приёмов использования цикла
for
. - Циклы for в Python – обучающий урок по применению цикла
for
. - Как осуществить циклический обход, используя индексы счетчика, в Python – руководство по реализации циклического прохода со счётчиками.