Различие между функциями и генераторами
На этом этапе вы узнаете ключевые различия между обычными функциями Python и генераторами. Понимание этого различия является важным для написания эффективного и экономного по памяти кода, особенно при работе с большими наборами данных или бесконечными последовательностями.
Функции:
Функция представляет собой блок кода, выполняющий определенную задачу. Когда функция вызывается, она выполняет свой код, может выполнять вычисления и возвращает значение (или None
, если явного оператора return
нет). Состояние функции не сохраняется между вызовами.
Генераторы:
Генератор - это особый тип функции, которая использует ключевое слово yield
вместо return
. Когда вызывается генератор, он возвращает объект итератора. Каждый раз, когда вы запрашиваете значение у итератора, генератор выполняется до тех пор, пока не встретит оператор yield
. Затем генератор приостанавливается, сохраняет свое состояние и возвращает значение. В следующий раз, когда запрашивается значение, генератор возобновляет выполнение с того места, где остановился.
Покажем это на примере. Сначала создайте файл с именем function_vs_generator.py
в каталоге ~/project
с помощью редактора VS Code.
## ~/project/function_vs_generator.py
## Regular function
def square_numbers_function(numbers):
result = []
for number in numbers:
result.append(number * number)
return result
## Generator function
def square_numbers_generator(numbers):
for number in numbers:
yield number * number
## Example usage
numbers = [1, 2, 3, 4, 5]
## Using the function
function_result = square_numbers_function(numbers)
print("Function Result:", function_result)
## Using the generator
generator_result = square_numbers_generator(numbers)
print("Generator Result:", list(generator_result)) ## Convert generator to list for printing
Теперь выполните скрипт Python:
python ~/project/function_vs_generator.py
Вы должны увидеть следующий вывод:
Function Result: [1, 4, 9, 16, 25]
Generator Result: [1, 4, 9, 16, 25]
И функция, и генератор дают одинаковый результат. Однако ключевое различие заключается в том, как они это достигают. Функция вычисляет все квадраты и сохраняет их в списке перед возвратом. Генератор, с другой стороны, возвращает каждый квадрат по одному, только когда он запрашивается.
Для дальнейшего иллюстрации различия изменим скрипт, чтобы вывести тип возвращаемого объекта:
## ~/project/function_vs_generator.py
## Regular function
def square_numbers_function(numbers):
result = []
for number in numbers:
result.append(number * number)
return result
## Generator function
def square_numbers_generator(numbers):
for number in numbers:
yield number * number
## Example usage
numbers = [1, 2, 3, 4, 5]
## Using the function
function_result = square_numbers_function(numbers)
print("Function Result Type:", type(function_result))
## Using the generator
generator_result = square_numbers_generator(numbers)
print("Generator Result Type:", type(generator_result))
Выполните скрипт еще раз:
python ~/project/function_vs_generator.py
Вывод будет следующим:
Function Result Type: <class 'list'>
Generator Result Type: <class 'generator'>
Это ясно показывает, что функция возвращает list
, в то время как генератор возвращает объект generator
. Генераторы экономят память, потому что они не хранят все значения в памяти одновременно. Они генерируют значения по запросу.