ENIGMA AI
ENIGMA AI

Что такое генератор и подгенератор в Python?

встречается 9× Python middle language_specific

Как ответить

Генератор в Python — это функция с ключевым словом yield, которая при вызове возвращает объект-итератор. В отличие от обычной функции, она не выполняет код сразу, а сохраняет своё состояние между вызовами next() — это ленивая (lazy) последовательность, которая не хранит все элементы в памяти.

На практике генераторы решают две задачи: экономят память (например, при чтении файла построчно без загрузки всего в RAM) и позволяют строить бесконечные последовательности. Вот простой пример — генератор чисел Фибоначчи:

def fibonacci(limit):
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

for num in fibonacci(100):
    print(num)  # 0, 1, 1, 2, 3, 5, 8, 13 ... 89

Подгенератор (subgenerator) — это механизм, введённый в Python 3.3 с помощью конструкции yield from. Он позволяет одному генератору делегировать часть своей работы другому итерабельному объекту (генератору, списку, etc.). При этом вся логика передачи значений, обработки исключений и возврата результата происходит автоматически. Без yield from пришлось бы вручную пробрасывать send() и throw() — это утомительно и чревато ошибками.

Пример: у нас есть два генератора — один для чисел Фибоначчи, другой для простых чисел. Мы хотим объединить их в один поток без копирования в память:

def primes(limit):
    n = 2
    while n < limit:
        if all(n % d != 0 for d in range(2, int(n**0.5) + 1)):
            yield n
        n += 1

def combined(limit):
    yield from fibonacci(limit)
    yield from primes(limit)

for val in combined(50):
    print(val)  # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47

yield from особенно полезен в корутинах (asyncio), где часто используют делегирование одних корутин другим. Ещё один важный нюанс: подгенератор может возвращать значение через return, и оно становится значением всего yield from выражения — это удобно для цепочек генераторов.

В плане производительности генераторы легче списков: они не создают коллекцию в памяти, а отдают значения по одному. Однако стоимость вызова next() немного выше, чем доступ к элементу списка — это стоит учитывать при микросравнениях, но для подавляющего большинства задач разница незначительна.

На собеседовании, когда спрашивают про генераторы, 80% сценариев упираются в чтение потоков данных, пайплайны обработки и бесконечные последовательности. Подгенератор (yield from) всплывает реже, но знание его показывает понимание устройства итераторов на уровень выше базового.

Ключевые тезисы

  • Генератор — функция с yield, возвращающая итератор; лениво вычисляет значения.
  • Основные применения: экономия памяти (чтение файлов, обработка потоков) и бесконечные последовательности.
  • Подгенератор — это yield from, делегирующий итерацию другому итерабельному объекту; автоматически обрабатывает send/throw/close.
  • yield from упрощает композицию иерархических итераторов и корутин (asyncio).
  • Генераторы не хранят все значения, но next() дороже доступа по индексу — компромисс памяти и скорости.

Что спросят дальше

  • — В чём разница между генератором и итератором? Как они соотносятся?
  • — Что произойдёт, если внутри генератора возникнет исключение? Как его перехватить снаружи?
  • — Как yield from взаимодействует с return: может ли подгенератор вернуть значение, и как его получить?

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение