Генераторы Python: итераторы с эффективным использованием памяти

Узнайте, как использовать генераторы Python и операторы доходности для обработки огромных наборов данных с минимальным потреблением памяти. Главные выражения-генераторы.

Попробуйте в редакторе

Обзор

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

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

Вы также можете создавать генераторы, используя выражения-генераторы, которые используют синтаксис, идентичный синтаксису списков, но заключенный в круглые скобки `(...)` вместо скобок `[...]`. Это позволяет невероятно легко заменить понимание списка итераторами, эффективно использующими память. Избегая массивного выделения памяти, генераторы незаменимы для работы с большими журналами, потоковой передачи данных из баз данных или выполнения вычислений над математическими последовательностями бесконечной длины.

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

Пользовательский генератор, выдающий числа Фибоначчи и выражение генератора с эффективным использованием памяти.

def fibonacci_generator(limit):
    """Yields Fibonacci numbers up to the limit."""
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

# Instantiate generator
fib = fibonacci_generator(5)
print("--- Using Generator Function ---")
for num in fib:
    print(num)

# Generator expression (squares of numbers)
squares_gen = (x**2 for x in range(1, 1000000))
print("\n--- Using Generator Expression ---")
print(next(squares_gen))
print(next(squares_gen))
print(next(squares_gen))
Терминальный выход
--- Using Generator Function ---
0
1
1
2
3

--- Using Generator Expression ---
1
4
9

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

  • Построчное чтение файлов, которые слишком велики для оперативной памяти.
  • Генерация бесконечной последовательности идентификаторов или математических цифр
  • Потоковая передача записей базы данных в пакетном режиме для обработки вызовов API

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

В чем разница между доходностью и доходностью?

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

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

Это вызывает исключение StopIteration. В цикле for Python автоматически перехватывает это исключение, чтобы аккуратно завершить цикл.

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

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

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