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