yield
Yield — это ключевое слово в Python, которое используется для возврата из функции с сохранением состояния ее локальных переменных, и при повторном вызове такой функции выполнение продолжается с оператора yield, на котором ее работа была прервана. Любая функция, содержащая ключевое слово yield, называется генератором. Можно сказать, yield — это то, что делает ее генератором. Хотя оператор yield в Python не отличается популярностью, но он имеет множество достоинств, о которых стоит знать.
Код #1: Демонстрация работы yield
# Код на Python3 для демонстрации
# использования ключевого слова yield
 
# генерация нового списка, состоящего
# только из четных чисел
def get_even(list_of_nums) :
    for i in list_of_nums:
        if i % 2 == 0:
            yield i
 
# инициализация списка
list_of_nums = [1, 2, 3, 8, 15, 42]
 
# вывод начального списка
print ("До фильтрации в генераторе: " +  str(list_of_nums))
 
# вывод только четных значений из списка
print ("Только четные числа: ", end = " ")
for i in get_even(list_of_nums):
    print (i, end = " ")
Вывод
До фильтрации в генераторе: [1, 2, 3, 8, 15, 42] 
Только четные числа:  2 8 42
Код #2
# Данная Python программа выводит
# числа от 1 до 15, возведенные в куб,
# используя yield и, следовательно, генератор
 
# Функция ниже будет бесконечно генерировать
# последовательность чисел в третьей степени,
# начиная с 1
def nextCube():
    acc = 1
 
    # Бесконечный цикл
    while True:
        yield acc**3                
        acc += 1 # После повторного обращения
                # исполнение продолжится отсюда
 
# Ниже мы запрашиваем у генератора 
# и выводим ровно 15 чисел
count = 1
for num in nextCube():
    if count > 15:
        break   
    print(num)
    count += 1
Вывод:
1
8
27
64
125
216
343
512
729
1000
1331
1728
2197
2744
3375
Преимущества yield:
- Поскольку генераторы автоматически сохраняют и управляют состояниями своих локальных переменных, программист не должен заботиться о накладных расходах, связанных с выделением и освобождением памяти.
 - Так как при очередном вызове генератор возобновляет свою работу, а не начинает с самого начала, общее время выполнения сокращается.
 
Недостатки yield:
- Иногда использование yield может вызвать ошибки, особенно если вызов функции не обрабатывается должным образом.
 - За оптимизацию времени работы и используемой памяти приходится платить сложностью кода, поэтому иногда трудно сходу понять логику, лежащую в его основе.
 
Практическое применение
Один из вариантов практического применения генераторов заключается в том, что при обработке большого объема данных и поиске в нем, выгодно использовать yield, так как зачастую нам не нужно повторно осматривать уже проверенные объекты. Такой подход значительно сокращает затраченное программой время. В зависимости от конкретной ситуации существует множество различных вариантов использования yield.
# Код Python3 для демонстрации
# использования ключевого слова yield
 
# Поиск слова pythonru в тексте
# Импорт библиотеки для работы 
# с регулярными выражениями
import re
# Этот генератор создает последовательность
# значений True: по одному на каждое
# найденное слово pythonru
# Также для наглядности он выводит
# обработанные слова
def get_pythonru (text) :
    text = re.split('[., ]+', text)
    for word in text:
        print(word)
        if word == "pythonru":
            yield True
 
# Инициализация строки, содержащей текст для поиска
text = "В Интернете есть множество сайтов, \
            но только один pythonru. \
            Программа никогда не прочтет \
            последнее предложение."
# Инициализация переменной с результатом
result = "не найден"
# Цикл произведет единственную итерацию
# в случае наличия в тексте pythonru и 
# не сделает ни одной, если таких слов нет
for j in get_pythonru(text):
    result = "найден"
    break
print ('Результат поиска: %s' % result)
Вывод
В
Интернете
есть
множество
сайтов
но
только
один
pythonru
Результат поиска: найден