ENIGMA AI
ENIGMA AI

В чем разница между генератором и итератором?

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

Как ответить

Главное различие — в способе создания и поведения: итератор — это объект, реализующий протокол итерации (методы __iter__ и __next__), а генератор — это частный случай итератора, который создаётся с помощью функции с yield или генераторного выражения. По сути, любой генератор — итератор, но не наоборот.

На практике разница проявляется в удобстве и состоянии. Итератор требует явного класса с методами, где нужно вручную управлять состоянием (например, индексом). Генератор делает то же самое «из коробки»: при каждом вызове yield он запоминает локальные переменные и точку остановки, а при следующем next() продолжает оттуда.

Вот как выглядит реализация простого итератора для последовательности чисел:

class Counter:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.limit:
            raise StopIteration
        self.current += 1
        return self.current - 1

То же самое через генератор:

def counter(limit):
    n = 0
    while n < limit:
        yield n
        n += 1

Генератор короче, а поведение идентичное. Ещё одно отличие: генератор создаётся вызовом функции, и это ленивый объект, который не хранит все значения в памяти. Итератор тоже может быть ленивым (как в примере выше), но генератор — это рекомендуемый способ, потому что писать меньше кода и меньше шансов ошибиться с состоянием.

Также стоит упомянуть типы: итераторы — это любые объекты с протоколом. Например, list — итерируемый объект, но не итератор (у него есть __iter__, который возвращает итератор). Встроенные функции iter() и next() работают с обоими. Генераторы — это итераторы, которые дополнительно поддерживают send(), throw(), close() для сопрограмм.

На собеседовании я обычно упоминаю, что генераторы удобны для бесконечных последовательностей и потоковой обработки (например, чтение файла построчно). Итераторы в чистом виде встречаются реже — только когда нужно переопределить итерацию для сложного класса или сделать одноразовый проход.

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

  • Итератор — объект с методами __iter__ и __next__, генератор — частный случай итератора, создаваемый через yield или выражение (i for i in range()).
  • Генератор автоматически управляет состоянием (локальные переменные), итератор требует ручного хранения (например, индекса).
  • Генераторы ленивы (вычисляют значения на лету), не хранят всю последовательность в памяти.
  • Генераторы поддерживают методы send/throw/close для двусторонней связи, обычные итераторы — только next.
  • Любой генератор — итератор, но не любой итератор — генератор.

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

  • — Что произойдёт, если вызвать next() на генераторе после того, как он исчерпан?
  • — Можно ли сделать итератор, который можно обходить несколько раз (как список)? Как это связано с отличием от генератора?
  • — Приведите пример, когда вы предпочли бы написать свой класс-итератор, а не использовать генератор.

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

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

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