Python Glossary Русский

all Python 3Iterators & generatorsterm

Generator function — yield

generators

A function with yield is a generator function. It returns a generator. Execution is suspended at each yield.

Syntax

def gen():
    yield value

Calling a generator function runs none of its body — it only builds a generator object; the code starts at the first next() or the first loop iteration. Generators are single-pass: once exhausted, a second for over the same variable silently yields nothing, which bites people who want to iterate twice or take len() first. The whole point is producing items one at a time instead of materialising a list, which is what makes huge or infinite sequences workable.

Examples

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))  # → [] исчерпан

See also

Open in the full glossarydocs.python.orgReport an inaccuracy