Python Glossary English

все Python 3Итераторы и генераторыпонятие

Generator function — yield

генераторы

Функция с yield — генераторная функция. Возвращает генератор. Выполнение приостанавливается при yield.

Синтаксис

def gen():
    yield value

Вызов генераторной функции не выполняет ни одной строки её тела — только создаёт объект-генератор; код стартует при первом next() или на первой итерации цикла. Генератор одноразовый: после того как он исчерпан, повторный for по той же переменной молча даст ноль итераций — это ловушка, когда результат хотят обойти дважды или сначала посчитать len(). Смысл конструкции — считать элементы по одному и не держать в памяти весь список, поэтому она уместна для больших или бесконечных последовательностей.

Примеры

def count_up(n):
    i = 0
    while i < n:
        yield i
        i += 1
for x in count_up(4):
    print(x, end=' ')  # → 0 1 2 3
# Бесконечный генератор
def naturals():
    n = 1
    while True:
        yield n
        n += 1
from itertools import islice
print(list(islice(naturals(), 5)))  # → [1,2,3,4,5]
# Ленивые вычисления
def read_large_file(path):
    # Открывает файл ленивно
    with open(path) as f:
        for line in f:
            yield line.strip()
    # Сохраняет память!
# Состояние между вызовами
def running_total(lst):
    total = 0
    for x in lst:
        total += x
        yield total
print(list(running_total([1,2,3,4])))  # → [1,3,6,10]
# Фибоначчи-генератор
def fib_gen():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a+b
g = fib_gen()
print([next(g) for _ in range(8)])  # → [0,1,1,2,3,5,8,13]
# send() — отправить значение в генератор
def accumulator():
    total = 0
    while True:
        value = yield total
        if value is not None:
            total += value
acc = accumulator()
next(acc)  # инициализация
print(acc.send(10))  # → 10
print(acc.send(5))   # → 15
# Генератор можно обходить только раз
g2 = count_up(3)
print(list(g2))  # → [0,1,2]
print(list(g2))  # → [] исчерпан

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности