Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Итерация генератора в Python
Генератор — это функция, которая использует yield для возврата значений по одному. Это мощный инструмент для создания итеративных последовательностей с минимальным использованием памяти.
Как работает генератор
Когда ты вызываешь функцию-генератор, она не выполняется сразу. Вместо этого возвращается объект генератора:
def simple_generator():
print("Начало")
yield 1
print("После первого yield")
yield 2
print("После второго yield")
yield 3
print("Конец")
# Генератор создан, но код не выполнен
gen = simple_generator()
print(type(gen)) # <class generator>
Итерация: step-by-step
Процесс итерации происходит через вызовы встроенной функции next():
# Первый вызов next()
value1 = next(gen) # Выведет: "Начало", вернёт 1
print(value1) # 1
# Второй вызов next()
value2 = next(gen) # Выведет: "После первого yield", вернёт 2
print(value2) # 2
# Третий вызов next()
value3 = next(gen) # Выведет: "После второго yield", вернёт 3
print(value3) # 3
# Четвёртый вызов next() — нет больше yield
try:
next(gen) # Выведет: "Конец"
except StopIteration:
print("Генератор исчерпан")
Итерация с for loop (автоматическая)
Цикл for автоматически вызывает next() и ловит StopIteration:
for value in simple_generator():
print(f"Получено: {value}")
# Эквивалентно:
gen = simple_generator()
while True:
try:
value = next(gen)
print(f"Получено: {value}")
except StopIteration:
break
Протокол итератора
Генератор реализует протокол итератора:
class MyIterator:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self # Возвращает себя
def __next__(self):
if self.current >= self.max:
raise StopIteration
self.current += 1
return self.current
# Генератор — то же самое, но проще
def my_generator(max):
current = 0
while current < max:
current += 1
yield current
Практические примеры
1. Генератор чисел Фибоначчи
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(10):
print(num, end=" ") # 0 1 1 2 3 5 8 13 21 34
2. Генератор чтения файла по строкам
def read_large_file(filepath):
with open(filepath) as f:
for line in f:
yield line.rstrip("\n")
# Не загружает весь файл в память
for line in read_large_file("huge_file.txt"):
process(line)
3. Двусторонний генератор (send)
def echo_generator():
value = None
while True:
value = (yield value) # Получить значение
gen = echo_generator()
next(gen) # Инициализация (обязательно перед send)
print(gen.send("Hello")) # Отправить значение → Hello
print(gen.send("World")) # Отправить значение → World
Производительность: Генератор vs Список
# Список — загружает ВСЁ в память сразу
def number_list(n):
result = []
for i in range(n):
result.append(i)
return result
# Генератор — ленивые вычисления
def number_generator(n):
for i in range(n):
yield i
# Список использует O(n) памяти
list_result = number_list(1_000_000) # ~40 MB
# Генератор использует O(1) памяти
gen_result = number_generator(1_000_000) # ~100 bytes
Ключевые точки
- Лень вычислений — значения вычисляются только при запросе
- Состояние сохраняется — между
yieldсохраняются локальные переменные - StopIteration — исключение сигнализирует конец последовательности
- Эффективность памяти — идеальны для больших наборов данных
- Однократное использование — генератор можно итерировать только один раз