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 приостанавливает выполнение функции и возвращает значение, сохраняя текущее состояние функции для последующего возобновления.