← Назад к вопросам

Как перебрать список, не используя for и итератор в Python?

1.3 Junior🔥 121 комментариев
#Python Core

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обход списка без for и итератора

В Python есть несколько креативных способов пройтись по списку без явного использования for цикла и итератора.

1. Рекурсия

def traverse_recursive(items, index=0):
    """Рекурсивно обходит список"""
    if index >= len(items):
        return
    
    print(items[index])
    traverse_recursive(items, index + 1)

my_list = [1, 2, 3, 4, 5]
traverse_recursive(my_list)
# Вывод: 1, 2, 3, 4, 5

# С аккумулятором результатов
def process_recursive(items, index=0, result=None):
    if result is None:
        result = []
    
    if index >= len(items):
        return result
    
    result.append(items[index] * 2)  # обрабатываем
    return process_recursive(items, index + 1, result)

result = process_recursive([1, 2, 3])
print(result)  # [2, 4, 6]

2. map() — функциональное программирование

items = [1, 2, 3, 4, 5]

# Применяем функцию к каждому элементу
result = list(map(lambda x: x * 2, items))
print(result)  # [2, 4, 6, 8, 10]

# map() ленив, поэтому не выполняет сразу
mapped = map(print, items)  # ничего не печатается
list(mapped)  # теперь печатается: 1 2 3 4 5

# Несколько списков одновременно
list1 = [1, 2, 3]
list2 = [10, 20, 30]
result = list(map(lambda x, y: x + y, list1, list2))
print(result)  # [11, 22, 33]

3. filter() — фильтрация

items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Фильтруем чётные
even = list(filter(lambda x: x % 2 == 0, items))
print(even)  # [2, 4, 6, 8, 10]

# Без lambda
def is_positive(x):
    return x > 5

filtered = list(filter(is_positive, items))
print(filtered)  # [6, 7, 8, 9, 10]

4. reduce() — свёртка (fold)

from functools import reduce

items = [1, 2, 3, 4, 5]

# Суммируем все элементы
total = reduce(lambda acc, x: acc + x, items)
print(total)  # 15

# Произведение
product = reduce(lambda acc, x: acc * x, items)
print(product)  # 120

# С начальным значением
with_initial = reduce(lambda acc, x: acc + x, items, 100)
print(with_initial)  # 115

# Более сложный пример: группировка
from functools import reduce

def group_by_parity(acc, x):
    """Разбивает на чётные и нечётные"""
    if x % 2 == 0:
        acc['even'].append(x)
    else:
        acc['odd'].append(x)
    return acc

items = [1, 2, 3, 4, 5, 6]
result = reduce(group_by_parity, items, {'even': [], 'odd': []})
print(result)  # {'even': [2, 4, 6], 'odd': [1, 3, 5]}

5. List comprehension (не цикл, но похож)

items = [1, 2, 3, 4, 5]

# Хотя технически это цикл, это не `for` statement в чистом виде
result = [x * 2 for x in items]
print(result)  # [2, 4, 6, 8, 10]

# С условием
even = [x for x in items if x % 2 == 0]
print(even)  # [2, 4]

# Вложенный comprehension
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in matrix for x in row]
print(flat)  # [1, 2, 3, 4, 5, 6]

6. enumerate() с рекурсией

def process_with_index(items, it=None):
    """Обходит с индексом без for"""
    if it is None:
        it = enumerate(items).__next__
    
    try:
        index, value = it()
        print(f"Index {index}: {value}")
        return process_with_index(items, it)
    except StopIteration:
        return

process_with_index([10, 20, 30])
# Index 0: 10
# Index 1: 20
# Index 2: 30

7. while с индексом (технически не for)

items = [1, 2, 3, 4, 5]
i = 0

while i < len(items):
    print(items[i])
    i += 1
# Вывод: 1, 2, 3, 4, 5

# С pop() — деструктивно
items_copy = [1, 2, 3, 4, 5]

while items_copy:
    print(items_copy.pop(0))
# Вывод: 1, 2, 3, 4, 5
# items_copy теперь пуст

8. exec() — динамическое выполнение

items = [1, 2, 3, 4, 5]

# Очень не рекомендуется, но технически возможно
code = """
result = []
index = 0
while index < len(items):
    result.append(items[index])
    index += 1
"""

locals_dict = {'items': items, 'result': None}
exec(code, {}, locals_dict)
print(locals_dict['result'])  # [1, 2, 3, 4, 5]

9. Декоратор callback

def process_list(callback):
    """Обходит список через callback"""
    def inner(items, index=0):
        if index >= len(items):
            return
        callback(items[index])
        inner(items, index + 1)
    return inner

@process_list
def my_processor(item):
    print(f"Processing: {item}")

my_processor([10, 20, 30])
# Processing: 10
# Processing: 20
# Processing: 30

10. asyncio с асинхронной итерацией (в Python 3.6+)

import asyncio

async def process_async(items):
    """Обходит асинхронно"""
    async for item in async_generator(items):
        print(item)

async def async_generator(items):
    """Асинхронный генератор"""
    for item in items:
        yield item
        await asyncio.sleep(0.1)

asyncio.run(process_async([1, 2, 3, 4, 5]))

11. Функциональное composition

from functools import reduce

def compose(*functions):
    """Комбинирует функции"""
    def inner(arg):
        return reduce(lambda x, f: f(x), functions, arg)
    return inner

def double(x):
    return x * 2

def add_ten(x):
    return x + 10

def to_string(x):
    return str(x)

# Применяем функции в порядке
pipeline = compose(double, add_ten, to_string)
result = pipeline(5)
print(result)  # "20" (5 * 2 = 10, 10 + 10 = 20, to_string = "20")

12. Generator expression (ленивый обход)

items = [1, 2, 3, 4, 5]

# Генератор не выполняет сразу
gen = (x * 2 for x in items)

print(next(gen))  # 2
print(next(gen))  # 4
print(next(gen))  # 6

# Или со специальной функцией
def iterate_with_generator(items):
    gen = (item for item in items)
    while True:
        try:
            print(next(gen))
        except StopIteration:
            break

iterate_with_generator([10, 20, 30])

Сравнение подходов

МетодПроизводительностьЧитаемостьРекомендуемость
map/filterХорошаяСредняяДа, для функционального стиля
reduceХорошаяНизкаяДля специфичных операций
РекурсияМедленнаяСредняяНет, risk переполнения стека
whileБыстраяХорошаяДа, если нужна прямая работа с индексом
List comprehensionОтличнаяОтличнаяДа, предпочтительно
Generator expressionОтличнаяХорошаяДа, для больших данных

Практический пример: реальное использование

from functools import reduce

# Задача: преобразовать список чисел, фильтровать, суммировать
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Вариант 1: List comprehension (лучший)
result1 = sum(x * 2 for x in data if x % 2 == 0)

# Вариант 2: map + filter
result2 = sum(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, data)))

# Вариант 3: reduce
result3 = reduce(
    lambda acc, x: acc + (x * 2) if x % 2 == 0 else acc,
    data,
    0
)

print(result1, result2, result3)  # 60 60 60

Лучшие практики

List comprehension — самый Pythonic способ. map/filter — для функционального стиля. reduce — только для сложных операций. Рекурсия — избегай на больших списках (StackOverflow). while — если действительно нужна прямая работа с индексом. Избегай exec/eval — угроза безопасности.