Как использовать генераторы в Python (оператор доходности)

Узнайте, как писать генераторы на Python. Изучите ключевое слово доходности, ленивые вычисления, оптимизацию памяти и сравните генераторы со структурами списков.

Попробуйте это решение в редакторе

Обзор

При работе с огромными наборами данных, файлами журналов или бесконечными потоками данных одновременная загрузка всех элементов в память (например, возврат большого списка) может легко исчерпать оперативную память системы и привести к сбою вашего приложения. Python предлагает блестящее решение с эффективным использованием памяти: генераторы.

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

Поскольку вычисления генератора выполняются лениво, они используют почти нулевую память независимо от размера набора данных. Python также поддерживает выражения-генераторы, которые используют синтаксис в скобках `(x вместо x в данных)` для создания облегченных встроенных генераторов без объявления полных функций.

Код и вывод выполнения

Этот скрипт демонстрирует создание последовательностей с использованием функций-генераторов с оператором доходности и выражениями-генераторами.

# 1. Generator function using yield
def count_up_to(limit):
    count = 1
    while count <= limit:
        yield count
        count += 1

# Instantiating the generator
counter = count_up_to(3)
print("Memory safe generator instantiated.")

# Fetching values manually
print("Next 1:", next(counter))
print("Next 2:", next(counter))
print("Next 3:", next(counter))

# 2. Iterating with a for loop (automatically handles StopIteration)
print("\n--- Looping over generator ---")
for num in count_up_to(4):
    print("Num:", num)

# 3. Generator expression (Shorthand syntax)
squares_gen = (x**2 for x in range(1, 4))
print("\nGenerator expression elements:")
print(list(squares_gen)) # Cast to list to print all elements
Терминальный выход
Memory safe generator instantiated.
Next 1: 1
Next 2: 2
Next 3: 3

--- Looping over generator ---
Num: 1
Num: 2
Num: 3
Num: 4

Generator expression elements:
[1, 4, 9]

Пошаговая реализация

  • Определите функцию, используя стандартное ключевое слово def.
  • Используйте ключевое слово yield вместо return, чтобы вернуть значения обратно в поток итератора.
  • Выполните итерацию генератора с помощью цикла for или вызовите встроенную функцию next(gen) для извлечения значений.
  • Используйте выражения-генераторы (с использованием круглых скобок) для простых встроенных ленивых преобразований.

Часто задаваемые вопросы

В чем главное преимущество генераторов перед списками?

Эффективность памяти. Списки хранят все элементы в оперативной памяти одновременно, а генераторы выдают элементы один за другим по требованию, что позволяет обрабатывать наборы данных, размер которых превышает общий объем памяти вашей системы.

Что происходит, когда в генераторе заканчиваются предметы?

Python вызывает исключение StopIteration. Цикл for автоматически перехватывает это исключение, чтобы корректно выйти из цикла, но вызов next() на исчерпанном генераторе вручную приведет к выдаче исключения.

Связанные темы

Рекомендуемые ресурсы Python

Расширьте свои знания с помощью соответствующих интерактивных руководств, шпаргалок и сравнений кода.