← Назад к вопросам

Как сделать из итератора генератор в Python?

2.0 Middle🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Преобразование итератора в генератор

Технически итератор и генератор — это близкие концепции, но их можно преобразовать друг в друга.

1. Основные определения

Итератор — объект с методами __iter__() и __next__():

class MyIterator:
    def __init__(self, max):
        self.current = 0
        self.max = max
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current < self.max:
            self.current += 1
            return self.current
        raise StopIteration

it = MyIterator(3)
for value in it:
    print(value)  # 1, 2, 3

Генератор — функция с yield, автоматически возвращает итератор:

def my_generator(max):
    current = 0
    while current < max:
        current += 1
        yield current

gen = my_generator(3)
for value in gen:
    print(value)  # 1, 2, 3

2. Преобразование итератора в генератор

def iterator_to_generator(iterator):
    """Преобразует итератор в генератор"""
    for value in iterator:
        yield value

# Использование
my_iter = MyIterator(3)
gen = iterator_to_generator(my_iter)
print(list(gen))  # [1, 2, 3]

3. Преобразование класса-итератора в класс-генератор

# ❌ Класс итератор (сложно)
class RangeIterator:
    def __init__(self, max):
        self.current = 0
        self.max = max
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current < self.max:
            self.current += 1
            return self.current
        raise StopIteration

# ✅ Функция-генератор (просто)
def range_generator(max):
    current = 0
    while current < max:
        current += 1
        yield current

4. Преобразование встроенных итераторов

# iter() → список через генератор
my_list = [1, 2, 3]
it = iter(my_list)

gen = (x for x in it)  # Comprehension
print(list(gen))  # [1, 2, 3]

# Или явно
def iter_to_gen(it):
    for item in it:
        yield item

gen = iter_to_gen(iter([1, 2, 3]))
print(list(gen))  # [1, 2, 3]

5. Практические примеры

Читать файл через итератор → генератор:

# Итератор
class FileIterator:
    def __init__(self, filename):
        self.file = open(filename)
    
    def __iter__(self):
        return self
    
    def __next__(self):
        line = self.file.readline()
        if not line:
            self.file.close()
            raise StopIteration
        return line

# Генератор (лучше)
def file_generator(filename):
    with open(filename) as f:
        for line in f:
            yield line

for line in file_generator('data.txt'):
    print(line.strip())

Преобразовать произвольный итератор:

import itertools

# Есть итератор
it = iter([1, 2, 3, 4, 5])

# Преобразуем в генератор
def iterable_to_generator(iterable):
    for item in iterable:
        yield item

gen = iterable_to_generator(it)
print(list(gen))  # [1, 2, 3, 4, 5]

6. Сравнение

         | Код   | Память | Простота | Отладка
---------|-------|--------|----------|----------
Итератор | Много | Экономно| Сложно  | Сложно
Генератор| Мало  | Экономно| Просто  | Просто

7. Когда использовать генераторы

# ✅ Генератор: для больших данных
def read_large_file(filename):
    with open(filename) as f:
        for line in f:
            yield line.strip()

# Не загружает весь файл в память
for line in read_large_file('huge_file.txt'):
    process(line)

Итог

Преобразование итератора → генератор:

def iter_to_gen(iterator):
    for item in iterator:
        yield item

Генераторы удобнее, экономнее по памяти и проще для чтения. Используй их вместо класса-итератора в 99% случаев.