Генераторы Python — это особый тип функций в Python. Они генерируют значения шаг за шагом и таким образом обеспечивают работу с эффективным использованием памяти.
Что такое генераторы Python?
Генераторы Python — это специальные функции, которые возвращают итератор Python. Способ создания генераторов Python аналогичен обычному определению функции. Разница заключается в деталях: вместо оператора return у генераторов есть так называемый оператор yield. Кроме того, функции генератора, такие как итераторы, также реализуют функцию next().
Ключевое слово доходность
Если вы знакомы с другими языками программирования или Python, то вы знакомы с оператором return. Это используется для передачи значений, вычисленных функциями, вызывающему экземпляру в программном коде. После того, как оператор возврата функции достигнут, функция завершается, и ее выполнение завершается. При необходимости функцию можно просто снова вызвать.
Yield ведет себя по-другому: ключевое слово заменяет оператор return в генераторах Python. Теперь, когда вы вызываете свой генератор, он возвращает значение, которое вы передали оператору yield. Однако после этого генератор Python не завершается, а только прерывается. Текущее состояние функции генератора более-менее сохраняется. Когда вы снова вызываете функцию генератора, вы переходите к сохраненной позиции.
Области применения генераторов Python
Благодаря тому, что генераторы Python работают по принципу » ленивых вычислений » и оценивают значения только тогда, когда они действительно нужны, функции-генераторы идеально подходят для работы с очень большими объемами данных.
Обычная функция сначала загрузит все содержимое файла в переменную и, следовательно, в вашу память. При больших объемах данных вашей локальной памяти может не хватить, и процесс приведет к ошибке MemoryError. Подобных проблем можно легко избежать с помощью генераторов, читая файл построчно. Ключевое слово yield возвращает значение, которое вам нужно в данный момент, а затем приостанавливает выполнение функции до следующего вызова функции, который работает с другой строкой файла.
Но генераторы Python значительно облегчают не только обработку больших объемов данных, но и работу с бесконечностью. Поскольку локальная память ограничена, генераторы — единственный способ создать бесконечные списки или что-то подобное в Python.
Чтение файлов CSV с помощью генераторов Python
Как уже упоминалось, генераторы особенно подходят для работы с большими объемами данных. Следующая программа позволяет считывать файл CSV построчно с эффективным использованием памяти :
import csv def csv_lesen(dateiname): with open(dateiname, 'r') as datei: tmp = csv.reader(datei) for zeile in tmp: yield zeile for zeile in csv_lesen('test.csv'): print(zeile)
В примере кода мы сначала импортируем модуль csv, чтобы получить доступ к функциям Python для обработки файлов CSV. Затем вы увидите определение генератора Python под названием «csv_lesen», которое, как и определения функций, начинается с ключевого слова «def». После того, как файл открыт, python-for-loop выполняет итерацию по файлу строка за строкой. Каждая строка возвращается с ключевым словом «урожайность».
Вне функции генератора строки, возвращаемые генератором Python, выводятся на консоль по одной за раз. Для этого используется функция печати Python.
Создавайте бесконечные структуры данных с помощью генераторов Python
Логически бесконечная структура данных не может храниться локально на вашем компьютере. Однако бесконечные структуры данных необходимы для некоторых приложений. Здесь также помогают функции-генераторы, так как они обрабатывают все элементы один за другим и при этом не перегружают память. Пример бесконечной последовательности натуральных чисел может выглядеть следующим образом в коде Python:
def natuerliche_zahlen(): n = 0 while True: yield n n += 1 for zahl in nateurlilche_zahlen(): print(zahl)
Во-первых, определяется генератор Python под названием «natural_numbers», который определяет начальное значение переменной «n». Затем запускается цикл Python, который работает бесконечно. При «выходе» возвращается текущее значение переменной и прерывается выполнение функции-генератора. Если функция вызывается снова, ранее выведенное число увеличивается на 1, и генератор снова запускается до тех пор, пока интерпретатор не встретит ключевое слово «выход». Числа, сгенерированные генератором, выводятся в цикле for ниже функции генератора. Если программу не прерывать вручную, она работает бесконечно.
Сокращение для генераторов Python
Генераторы списков позволяют создавать списки Python всего за одну строку кода. Подобное сокращенное обозначение также существует для генераторов. Давайте посмотрим на генератор, который увеличивает числа от 0 до 9 на 1. Он похож на генератор, который мы использовали для генерации бесконечной последовательности натуральных чисел.
def natuerliche_zahlen(): n = 0 while n <= 9: yield n n+=1
Если вы хотите написать этот генератор в одной строке кода, используйте оператор for в скобках, как в следующем примере:
Если вы теперь хотите вывести этот генератор, вы получите следующий вывод:
Так вам показывают, где в вашей памяти находится созданный объект Генератор. Чтобы получить доступ к выходным данным вашего генератора, вы можете использовать функцию next():
print(next(increment_generator)) print(next(increment_generator)) print(next(increment_generator))
Этот раздел кода обеспечивает следующий вывод, в котором числа от 0 до 2 увеличены на 1:
1 2 3
Генераторы против списков
Сокращенная запись генераторов сильно напоминает списки. Единственная визуальная разница заключается в квадратных скобках: в то время как вы используете квадратные скобки для понимания, вы используете круглые скобки для создания генераторов Python. Однако внутри есть гораздо более фундаментальная разница: генераторы используют гораздо меньше памяти, чем списки.
import sys increment_liste = [n + 1 for n in range(100)] increment_generator = (n + 1 for n in range(100)) print(sys.getsizeof(increment_liste)) print(sys.getsizeof(increment_generator))
Приведенная выше программа печатает объем памяти списка и эквивалентный генератор:
912 120
В то время как для списка требуется 912 байт дискового пространства, генератору достаточно всего 120 байт. Эта разница становится еще более значительной, когда увеличивается объем обрабатываемых данных.








