Чем отличаются итератор и генератор в Python

Ответ

И итератор, и генератор в Python предоставляют способ последовательного доступа к элементам коллекции, не загружая всю коллекцию в память. Однако они создаются и работают по-разному.

Итератор — это объект, реализующий протокол итерации, который включает в себя методы __iter__() и __next__(). Обычно создается как экземпляр класса.

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

Ключевые различия:

Характеристика Итератор (класс) Генератор (функция с yield)
Создание Требует написания класса с методами __iter__ и __next__. Создается функцией с yield или генераторным выражением.
Состояние Управляется вручную через атрибуты экземпляра (например, self.index). Сохраняется автоматически между вызовами yield.
Код Более громоздкий. Компактный и более читаемый для простых случаев.

Пример:

# 1. Итератор в виде класса
class NumberIterator:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0

    def __iter__(self):
        # Возвращает сам объект-итератор
        return self

    def __next__(self):
        # Возвращает следующий элемент или вызывает StopIteration
        if self.current < self.limit:
            self.current += 1
            return self.current
        else:
            raise StopIteration

# 2. Генератор в виде функции
def number_generator(limit):
    current = 0
    while current < limit:
        current += 1
        yield current # Приостанавливает выполнение и возвращает значение

# Использование
print("Итератор:", list(NumberIterator(3))) # Вывод: [1, 2, 3]
print("Генератор:", list(number_generator(3))) # Вывод: [1, 2, 3]

Вывод: Генераторы — это синтаксический сахар для создания итераторов. Их следует предпочитать для простых последовательностей из-за краткости и читаемости. Полноценные классы-итераторы нужны, когда требуется сложная логика управления состоянием или дополнительные методы.

Ответ 18+ 🔞

А, ну ты про итераторы и генераторы в Python спрашиваешь? Ёпта, классика, блядь. Сейчас разжуём, в чём тут, сука, разница, а то народ путается, как мартышлюшка в цирке.

Смотри, оба этих зверя — и итератор, и генератор — они тебе элементы коллекции по одному выдают, не загружая всё это добро в память сразу. Это чтобы комп не накрылся медным тазом, если данных овердохуища. Но делают они это по-разному, пиздец как.

Итератор — это такой серьёзный дядька в пальто. Нужно написать целый класс, там __iter__, там __next__, всё по протоколу, блядь. Самому за всем следишь, где ты остановился, что вернул. Работа для перфекциониста, сука.

Генератор — это ленивый, но гениальный племянник этого дядьки. Берёшь обычную функцию, вставляешь в неё волшебное слово yield, и вуаля — она превращается в генератор. Всё состояние между вызовами сохраняется само, как по маслу. Красота, ёперный театр!

Короче, таблица, чтобы не ебать мозг:

Признак Итератор (класс) Генератор (функция с yield)
Как создать Писать класс, методы, атрибуты — заебись. Написать функцию и сказать yield. Проще некуда.
Кто хранит состояние Ты, блядь, сам, через self.current и прочую хуйню. Интерпретатор, сука, всё сам запоминает.
Объём кода Громоздкий, как хуй с винтом. Компактный и элегантный, почти поэзия.

Ну и пример, чтобы совсем всё стало ясно, как божий день:

# 1. Итератор. Написал — и сам от себя охуел, сколько кода.
class NumberIterator:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0

    def __iter__(self):
        return self

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

# 2. Генератор. Посмотрел — и волнение ебать, как просто.
def number_generator(limit):
    current = 0
    while current < limit:
        current += 1
        yield current # Всё, стоп машина, запомнил где был и вернул значение.

# Используем, как в аптеке
print("Итератор:", list(NumberIterator(3))) # [1, 2, 3]
print("Генератор:", list(number_generator(3))) # [1, 2, 3]

Итог, блядь: Генераторы — это просто конфетка для 99% случаев. Используй их, не парься. А вот если тебе нужна какая-то хитрая жопа с дополнительной логикой, тогда уже лезь в дебри и пиши свой класс-итератор. Но честно? Чаще всего — да похуй, генератора хватает за глаза.