Что такое итератор
Итератор — это объект, который возвращает элементы по одному при вызове next() и «знает», где он сейчас в последовательности.
Формально итератор реализует два метода:
__iter__(), возвращающий сам итератор;
__next__(), который возвращает очередное значение или выбрасывает StopIteration, когда значения закончились.
Пример простого итератора:
class CountDown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
value = self.current
self.current -= 1
return value
for n in CountDown(3):
print(n) # 3, 2, 1
Класс явно хранит состояние и реализует протокол итератора.
Что такое генератор и yield
Генератор — это функция (или выражение), которая использует yield и при вызове возвращает объект‑генератор, то есть специальный итератор.
def countdown(start):
while start > 0:
yield start
start -= 1
for n in countdown(3):
print(n) # 3, 2, 1
Особенности yield:
При первом next() код выполняется до первого yield, возвращает значение и «замораживает» состояние функции.
Следующий next() продолжает выполнение сразу после yield, сохраняя локальные переменные.
Когда функция доходит до конца или до return, выбрасывается StopIteration.
То есть генератор хранит своё состояние внутри функции, без явной реализации __next__ и __iter__ вручную.
Чем генератор отличается от «обычного» итератора
Способ создания. Обычный итератор чаще реализуют как класс с методами __iter__ и __next__. Генератор создаётся функцией с yield или генераторным выражением (expr for ... in ...).
Объём кода. В генераторе не нужно самому хранить и обновлять состояние — всё делает интерпретатор. Код получается короче и проще.
Отношение между понятиями
Все генераторы — итераторы: у них есть __iter__ и __next__. Не все итераторы — генераторы: их можно писать классами без yield.
Память и ленивость
И генераторы, и итераторы обычно отдают значения по одному (лениво), не держа всю последовательность в памяти. Генераторы особенно удобны для больших/бесконечных последовательностей: чтение файла построчно, поток событий, последовательная обработка данных.
Фраза для собеседования
Итератор — это объект с __iter__ и __next__, который отдаёт элементы по одному и в конце бросает StopIteration. Генератор — это частный случай итератора, который создаётся функцией с yield и автоматически хранит своё состояние между вызовами next(). Генераторы позволяют писать итераторы в виде простой функции вместо отдельного класса.