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

Как используется генератор?

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

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

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

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

# Генераторы в Python

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

Синтаксис создания генератора

Генератор создаётся с помощью ключевого слова yield:

def simple_generator():
    yield 1
    yield 2
    yield 3

gen = simple_generator()
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# next(gen) вызовет StopIteration

Основные характеристики

1. Ленивое вычисление (Lazy Evaluation)

Значения вычисляются только при необходимости:

def count_to_n(n):
    i = 0
    while i < n:
        yield i
        i += 1

# Без генератора (памяти много):
data = [i for i in range(1000000)]

# С генератором (память минимальна):
for num in count_to_n(1000000):
    print(num)

2. Состояние сохраняется между вызовами

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
print(next(fib))  # 0
print(next(fib))  # 1
print(next(fib))  # 1
print(next(fib))  # 2
print(next(fib))  # 3

Практические примеры использования

1. Чтение больших файлов

def read_large_file(filepath, chunk_size=1024):
    with open(filepath, r) as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            yield chunk

# Память не переполнится даже при гигабайтном файле
for chunk in read_large_file(huge_file.txt):
    process(chunk)

2. Обработка потоков данных

def data_pipeline(data):
    for item in data:
        # Фильтрация
        if item > 0:
            # Преобразование
            yield item * 2

numbers = [1, -2, 3, -4, 5]
for result in data_pipeline(numbers):
    print(result)  # 2, 6, 10

3. Выражения-генераторы (Generator Expressions)

# Похоже на list comprehension, но экономит память
gen = (x**2 for x in range(10))
print(next(gen))  # 0
print(next(gen))  # 1
print(next(gen))  # 4

# Или через итерацию
for value in (x**2 for x in range(10)):
    print(value)

Двусторонняя коммуникация через send()

Генератор может получать значения через метод send():

def echo():
    value = None
    while True:
        value = yield
        print(f"Получено: {value}")

gen = echo()
next(gen)  # Инициализация
gen.send("Hello")  # Отправить значение
gen.send("World")  # Отправить ещё одно

Метод throw() для обработки исключений

def safe_generator():
    try:
        yield 1
        yield 2
    except ValueError as e:
        print(f"Ошибка: {e}")
        yield "восстановление"

gen = safe_generator()
print(next(gen))  # 1
gen.throw(ValueError, "Что-то пошло не так")
print(next(gen))  # восстановление

Преимущества генераторов

  1. Экономия памяти — вычисляются по требованию
  2. Производительность — начальная задержка минимальна
  3. Читаемость — код часто более понятен
  4. Бесконечные последовательности — можно работать с бесконечными потоками
  5. Pipeline обработки — легко создавать цепочки преобразований

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

  • Работа с большими данными
  • Потоковая обработка
  • API с постраничной выборкой
  • Обработка файлов
  • Создание бесконечных последовательностей
  • Pipeline преобразования данных

Генераторы — мощный инструмент для эффективной работы с данными в Python.