Что значит вызвать генератор?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Генераторы в Python
Генератор — это специальный тип функции, которая вместо return использует yield для возврата значений по одному. Вызов генератора создаёт объект-итератор, который запоминает своё состояние и продолжает выполнение с того же места при каждом обращении.
Как работает вызов генератора
Когда ты вызываешь функцию с yield, она не выполняется сразу. Вместо этого возвращается объект генератора:
def my_generator():
print("Начало")
yield 1
print("После первого yield")
yield 2
print("После второго yield")
yield 3
# Вызов генератора НЕ выполняет код, а только создаёт объект
gen = my_generator()
print(gen) # <generator object my_generator at 0x...>
Фактический код выполняется лениво — только когда ты запрашиваешь значения.
Итерирование по генератору
gen = my_generator()
# Способ 1: через next()
print(next(gen)) # "Начало" → 1
print(next(gen)) # "После первого yield" → 2
print(next(gen)) # "После второго yield" → 3
# next(gen) # StopIteration — конец
# Способ 2: через цикл for (удобнее)
gen = my_generator()
for value in gen:
print(value) # 1, 2, 3
Преимущества генераторов
1. Экономия памяти Вместо создания списка всех значений, генератор выдаёт их поодиночке:
# Плохо: список из миллиона чисел в памяти
def get_numbers():
return [i for i in range(1000000)]
# Хорошо: числа генерируются по мере надобности
def get_numbers_gen():
for i in range(1000000):
yield i
result1 = get_numbers() # ~ 8 MB в памяти
result2 = get_numbers_gen() # ~ 0 KB (объект генератора)
2. Лентивое вычисление Вычисления начинаются только когда нужны значения:
def process_large_file(filename):
with open(filename) as f:
for line in f:
yield line.strip()
# Файл читается построчно, не весь сразу
for line in process_large_file(huge.txt):
print(line)
3. Бесконечные последовательности Можешь создавать потоки значений без конца:
def infinite_counter():
count = 0
while True:
yield count
count += 1
counter = infinite_counter()
print(next(counter)) # 0
print(next(counter)) # 1
print(next(counter)) # 2
Выражения-генераторы
Они похожи на list comprehension, но экономят память:
# List comprehension (создаёт список)
list_nums = [x*2 for x in range(5)] # [0, 2, 4, 6, 8]
# Generator expression (создаёт генератор)
gen_nums = (x*2 for x in range(5))
print(next(gen_nums)) # 0
print(next(gen_nums)) # 2
Практический пример
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
for i in range(10):
print(next(fib), end=" ") # 0 1 1 2 3 5 8 13 21 34
Отправка значений в генератор
Генератор может получать данные через send():
def echo():
while True:
x = yield
if x is not None:
print(f"Получено: {x}")
gen = echo()
next(gen) # Инициализация
gen.send("Привет") # Получено: Привет
gen.send(42) # Получено: 42
Резюме
Вызов генератора — это создание объекта-итератора, который:
- Не выполняет код функции сразу
- Запоминает состояние между вызовами next()
- Генерирует значения лениво, по требованию
- Позволяет работать с бесконечными или очень большими последовательностями эффективно
Это мощный инструмент для оптимизации памяти и создания элегантного, функционального кода.