В создании итераторов в Python есть много составляющих; мы должны реализовать класс с методами __iter__() и __next__(), отслеживать состояния внутренних переменных, поднимать StopIteration, когда не было возвращаемых значений, и т. д. В данном руководстве разберем, как создать итератор с помощью генератора Yield в Python

Что такое генераторы в Python?
Генераторы в Python — это простые функции, которые возвращают итерируемый набор элементов по одному уникальным способом. Генераторы Питон используются для создания итераторов, но с другим подходом.
Если функция содержит хотя бы один оператор yield (может включать другие операторы yield или return), то она становится функцией-генератором.
Основное различие между обычными функциями и генераторами Python заключается в том, что оператор return полностью завершает функцию; оператор yield приостанавливает функцию, сохраняя все ее состояния и значения переменных, а затем продолжает последующие вызовы.
См. следующий пример генераторов в Python.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# app.py def createGenerator(): i = 1 print('Ronin') print(i) yield i i += 1 print('RedSkull') print(i) yield i i += 1 print('Rocket') print(i) yield i gen = createGenerator() next(gen) next(gen) next(gen) |
Смотрите вывод.

В приведенном выше примере следует отметить одну интересную вещь: значение переменной i запоминается между каждым вызовом.
В отличие от любых обычных функций, локальные переменные не уничтожаются, когда функция уступает. Кроме того, объект-генератор можно повторить только один раз.
Когда оператор yield выполняется, выполнение функции приостанавливается, и значение переменной не уничтожается, когда мы вызываем следующий оператор, он начинает выполнение. Когда снова выполняется оператор yield, выполнение функции останавливается и снова возобновляется выполнение. Вот почему мы можем видеть все значения.
Для циклов с генераторами
Мы можем использовать цикл for напрямую с генераторами. Мы можем отобразить значения, выполнив функцию next(). См. следующий пример.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# app.py def createGenerator(): i = 1 print('Ronin') yield i i += 1 print('RedSkull') yield i i += 1 print('Rocket') yield i for g in createGenerator(): print(g) |
Смотрите вывод.

Цикл for принимает итератор и перебирает его с помощью функции next(). Он автоматически завершается при поднятии StopIteration.
Выражение генератора Python
Простые генераторы можно легко создавать на лету, используя выражения генератора. Это упрощает создание генераторов.
Так же, как лямбда-функция создает анонимную функцию, выражение генератора создает анонимную функцию-генератор.
Синтаксис выражения генератора аналогичен синтаксису генератора списка в Python. Но квадратные скобки заменяются круглыми скобками.
Существенная разница между генератором списков и списковым генератором заключается в том, что в то время как списочный генератор создает весь список, генератор создает по одному элементу за раз.
Они немного ленивы, производят предметы только тогда, когда их просят. По этой причине выражение генератора гораздо более эффективно использует память, чем понимание списка.
См. приведенный ниже пример.
|
1 2 3 4 5 6 7 8 |
# app.py listK = [18, 19, 21, 29, 46] result =(i ** 2 for i in listK) print(next(result)) print(next(result)) print(next(result)) print(next(result)) |
Смотрите вывод.

Генераторное выражение можно использовать внутри функций. При таком использовании можно использовать круглые скобки.
Выше мы видим, что выражение генератора не сразу дало требуемый результат. Вместо этого он вернул объект-генератор, который производит элементы по запросу.
Что такое Python Yield?
Оператор yield в Python приостанавливает выполнение функции и отправляет значение обратно вызывающей стороне, но сохраняет достаточно состояния, чтобы позволить функции возобновиться с того места, где она была остановлена. При возобновлении функция продолжает выполнение сразу же после последнего выполнения yield.
Это позволяет его коду создавать ряды значений с течением времени, а не вычислять их сразу и отправлять обратно в виде списка. Yield используется в генераторах Python.
Функция-генератор определена как обычная функция, но всякий раз, когда ей нужно сгенерировать значение, она делает это с помощью ключевого слова yield, а не return.
Если тело определения содержит yield, функция автоматически становится функцией-генератором.
Различия между генератором и обычной функцией
- Функция-генератор содержит один или несколько операторов yield.
- Когда вызывается функция-генератор, она возвращает объект (итератор), но не сразу начинает выполнение.
- Такие функции, как __iter__() и __next__(), реализуются автоматически. Таким образом, мы можем перебирать элементы с помощью функции next().
- Как только оператор yield функции выполнен, функция приостанавливается и передает управление вызывающей стороне.
- Локальные переменные и их состояния запоминаются между последовательными вызовами.
- Наконец, когда функция завершается, StopIteration автоматически вызывается при дальнейших вызовах.
