Ответ
Генераторы в Python — это функции, которые используют ключевое слово yield для возврата итератора с ленивым (отложенным) вычислением. Их главная ценность — экономия памяти, так как они генерируют значения по одному по мере необходимости, а не хранят всю последовательность в памяти сразу.
Как это работает:
- При вызове функции-генератора она возвращает объект-генератор, но код не выполняется.
- При первой итерации (например,
next()или в циклеfor) выполнение идет до первогоyield. Значение послеyieldвозвращается, а состояние функции (локальные переменные, точка выполнения) «замораживается». - При следующей итерации выполнение возобновляется сразу после
yieldи продолжается до следующегоyieldили конца функции.
Пример с состоянием:
def fibonacci_generator(limit):
"""Генерирует числа Фибоначчи до limit."""
a, b = 0, 1
while a < limit:
yield a # Возвращаем текущее значение и «засыпаем»
a, b = b, a + b # Это состояние сохраняется между вызовами
# Использование
fib_gen = fibonacci_generator(50)
print(next(fib_gen)) # 0
print(next(fib_gen)) # 1
print(next(fib_gen)) # 1
print(next(fib_gen)) # 2
# Или в цикле (остальные числа)
for num in fib_gen:
print(num) # 3, 5, 8, 13, 21, 34
Ключевые преимущества и use-cases:
- Обработка больших файлов: Чтение файла построчно без загрузки всего в память.
def read_large_file(file_path): with open(file_path, 'r') as f: for line in f: yield line.strip() - Работа с бесконечными последовательностями: Поток данных, сенсоры.
-
Конвейеры обработки данных (generator pipeline): Можно соединять генераторы, передавая данные по цепочке.
def filter_even(numbers): for n in numbers: if n % 2 == 0: yield n def square(numbers): for n in numbers: yield n ** 2 # Ленивый конвейер: квадраты четных чисел pipeline = square(filter_even(range(100))) print(list(pipeline)[:5]) # [0, 4, 16, 36, 64] - Выражения-генераторы: Краткий синтаксис
(x**2 for x in range(10)).