> Напиши генератор в Python, который бесконечно возвращает числа (Python)

Уровень: senior · Роль: qa · Категория: Технические вопросы

Компании: YADRO

Стек: Python

> Пример ответа

Короткий ответ

Бесконечный генератор чисел в Python можно реализовать через yield в цикле while True. Например, генератор натуральных чисел: def natural_numbers(): n = 1; while True: yield n; n += 1. При каждом вызове next() генератор возобновляет выполнение с места последнего yield, что позволяет генерировать числа бесконечно без хранения их в памяти.

Подробное объяснение

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

Ключевые особенности:

  • Память не расходуется на хранение всей последовательности - генерируется только текущее значение.
  • Генератор можно комбинировать с другими итераторами, фильтровать, ограничивать через itertools.islice.
  • Для остановки бесконечной генерации используется StopIteration (явно или через break в потребителе).

На практике

На практике бесконечные генераторы полезны для:

  • потоковой обработки данных (например, чтение строк из файла или сетевого потока);
  • создания последовательностей Фибоначчи, простых чисел, случайных чисел с seed;
  • реализации пулов ID, счётчиков, таймеров;
  • ленивых вычислений, когда значения нужны по одному.

Важно помнить: если передать бесконечный генератор в list() или sum() без ограничения, программа зависнет. Всегда используйте itertools.islice, takewhile или явный break.

Пример кода

PYTHON
from itertools import islice
def infinite_numbers(start=0, step=1):
current = start
while True:
yield current
current += step
# Использование
gen = infinite_numbers(10, 2)
print(next(gen)) # 10
print(next(gen)) # 12
# Ограничение через islice
first_five = list(islice(infinite_numbers(), 5))
print(first_five) # [0, 1, 2, 3, 4]
# Цикл с break
for num in infinite_numbers():
if num > 3:
break
print(num) # 0, 1, 2, 3

Как отвечать на собеседовании

Начни с простого определения генератора и yield. Затем покажи минимальный пример с while True. Подчеркни ленивость вычислений и экономию памяти. Упомяни практические сценарии: потоковая обработка, последовательности, ID. Если спросят про остановку - расскажи про islice, break, StopIteration. Хорошо добавить сравнение с обычной функцией, возвращающей список: разница в памяти и времени для больших данных.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание механизма yield и состояния генератора;
  • умение работать с бесконечными последовательностями без утечек памяти;
  • знание стандартных инструментов (itertools) для ограничения и комбинирования;
  • способность объяснить разницу между генератором и итератором;
  • практическое мышление - когда такие генераторы реально нужны.

Типичные ошибки

  • Использование return вместо yield - функция завершится на первом значении.
  • Попытка преобразовать бесконечный генератор в список без ограничения - зависание.
  • Забывание про next() - попытка использовать генератор как обычный объект.
  • Путаница между генератором и генераторным выражением (например, (x for x in range(10))).
  • Неправильная работа с состоянием: сброс счётчика внутри цикла вместо внешней переменной.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью