yield и функции-генераторы
Инструкция yield в Python является одной из мощных и гибких возможностей языка, предназначенной для создания функций-генераторов (не путать с выражениями-генераторами списков!). Генераторы позволяют создавать итераторы простым и лаконичным способом, экономя память и повышая производительность программ.
Инструкция yield
Инструкция yield используется внутри функции для превращения её в генератор. В отличие от обычных функций, генераторы возвращают значение, но сохраняют своё состояние между вызовами, что позволяет возобновить выполнение с того места, где они были прерваны.
def simple_generator():
yield 1
yield 2
yield 3
gen = simple_generator()
print(next(gen)) # Выведет 1
print(next(gen)) # Выведет 2
print(next(gen)) # Выведет 3
Особенности использования yield
- Сохранение состояния: Генераторы сохраняют своё состояние между вызовами, что позволяет им продолжить выполнение с места, где они были прерваны
- Ленивые вычисления: Генераторы производят значения только "по требованию", что экономит память. Это особенно полезно при работе с большими данными или бесконечными последовательностями. Однако ошибки внутри функции могут появиться в середине вашего цикла for, а не сразу при вызове функции
- Автоматическое управление состоянием: Использование генераторов позволяет избежать необходимости в явном управлении состоянием и использовании вспомогательных переменных или структур данных
Примеры использования yield
Создание простого счетчика:
def counter():
count = 0
while True:
yield count
count += 1
count_gen = counter()
print(next(count_gen)) # 0
print(next(count_gen)) # 1
print(next(count_gen)) # 2
Создание последовательности чисел Фибоначчи от 1 до n:
def fibonacci(n):
a, b = 0, 1
for i in range(n):
yield a
a, b = b, a + b
fib_gen = fibonacci(10)
for i in fib_gen:
print(i)
Функции, в которых есть yield, возвращают итератор. Тот самый, который можно помещать внутрь цикла for.
Можно и вручную вызывать следующий элемент функцией next, что и было продемонстрировано в примерах выше.
Различия между yield и return
return завершает выполнение функции и возвращает значение.
yield приостанавливает выполнение функции и возвращает значение, сохраняя текущее состояние функции для последующего возобновления.