Получить доступ

Что такое генератор и чем он полезен?

JuniorИтераторы и генераторы
Ещё спрашивают так:
  • Как работает yield?
  • Чем генератор отличается от обычной функции?
  • Что такое yield from?
Коротко

Генератор — функция с yield: отдаёт значения по одному и замирает между ними, сохраняя состояние.

  • Ленивый: следующее значение вычисляется только по запросу
  • Память O(1) вместо целого списка — можно обрабатывать огромные и бесконечные потоки

А ещё Генератор проходится один раз; второй проход ничего не даст

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Если в теле функции есть yield, её вызов не выполняет код, а возвращает объект-генератор. Генератор — итератор: каждый next() выполняет тело до следующего yield, отдаёт значение и приостанавливается. Локальные переменные и место остановки сохраняются. Когда функция заканчивается, генератор бросает StopIteration, и цикл for завершается.

Зачем:

  • память — читать файл на 10 ГБ построчно, не загружая его целиком;
  • ленивость — значения считаются только если нужны: можно взять первые 10 из бесконечной последовательности;
  • конвейеры — генераторы удобно соединять в цепочку: прочитать → отфильтровать → преобразовать.

yield from other отдаёт все значения из другого итерируемого объекта — удобно для рекурсии и делегирования.

Ограничения: генератор исчерпывается после одного прохода; у него нет len() и доступа по индексу.

Пример

def read_lines(path):
    with open(path, encoding="utf-8") as f:
        for line in f:
            yield line.rstrip("\n")

def numbers():
    n = 0
    while True:          # бесконечный генератор
        yield n
        n += 1

from itertools import islice
list(islice(numbers(), 5))   # [0, 1, 2, 3, 4]

def flatten(items):
    for x in items:
        if isinstance(x, list):
            yield from flatten(x)
        else:
            yield x

Что хотят услышать

  • Механика yield: пауза и сохранение состояния.
  • Ленивость и экономия памяти с практическим примером.
  • Генератор — итератор, исчерпывается за один проход.
  • Знание yield from и генераторных выражений — плюс.

Частые ошибки

  • Пройти генератор второй раз и удивиться пустому результату.
  • Считать, что вызов функции с yield сразу выполняет её код.

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

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем