Материал: Разработка программных пакетов на языке Python. учебное пособие. Амоа К.А., Рындин Н.А

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

#Описание функции для решения уравнения.

#Используем рекурсию def solve (f , xO , n ) :

#Начальное приближение if n==O : return хО

#Рекурсивное соотношение else :

return solve ( f , f ( xO ) , n- 1 )

#Функция , определяющая уравнение de f eqn ( х ) :

#Значение функции return (x**2+5) / 6

#Решаем уравнение x=s 9lve ( eqn, 0, 10 )

#Отображаем результат

print (" Peшeниe уравнения : х = " , х )

Мы немного изменили программный код: частью переписали, частью – упростили. Функция solve() предназначена для решения уравнения, определяемого первым аргументом (ссылка на функцию уравнения f) с начальным приближением, определяемым вторым аргументом (обозначен как х0) по количеству итераций, определяемому третьим аргументом (обозначен как n).

Основу программного кода функции составляет условный оператор, в котором проверяется условие n == 0. Что означает истинность этого условия? Истинность этого условия означает, что мы вычисляем нулевое приближение для корня уравнения. Но нулевое приближение определяется вторым аргументом х0 функции solve(). Поэтому нет ничего удивительного в том, что при истинном условии n==0 командой return х0 значение х0 возвращается как результат функции solve() . Но если условие n==0 ложно, в качестве результата возвращается выражение sо1ve(f , f( х0) , n - 1) , в котором рекурсивно

вызывается функция solve ( ).

 

 

=

 

+56

Результат работы созданной нами функции solve ( ) проверяем для

решения уравнения

 

2

 

. С этой целью в программе описана функция

eqn(). В итоге получаем такой результат:

Решение уравнения: х = 0 . 9999925289581152

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

25

в том, что с помощью этой функции можно найти второй корень уравнения. Для этого лишь нужно представить в ином виде само уравнение – как мы это делали ранее.

3.4. Лямбда-функции

Мы уже знаем, что имя функции можно присвоить в качестве значения переменной, после чего через эту переменную допустимо ссылаться на функцию. Но в языке Python есть и другая "крайность": мы можем создать функцию, но имя ей не присваивать вовсе. Такие функции называются анонимными функциями или лямбда-функциями. Зачем подобные функции нужны – это вопрос отдельный. Можно привести как минимум несколько примеров, когда использование лямбда-функций представляется оправданным:

–передача лямбда-функции аргументом другой функции;

–возвращение функцией в качестве результата другой функции;

–однократное использование функции.

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

lambda аргументы: результат

У этой конструкции есть результат: ссылка на объект лямбда-функции. Поэтому в принципе lаmbdа-конструкцию можно присвоить в качестве значения переменной, тем самым определив, в общем-то, обычную функцию. Небольшой пример, иллюстрирующий некоторые аспекты объявления и использования лямбда-функций, приведен в листинге:

#Функция для отображения значения

#другой функции

def find_value (f, x):

print ("x =" , х , " - > f (x ) =" , f ( x ) )

#Переменной присваивается

#ссылка на лямбда-функцию my_func=lambda 0 x: l / (l +x* *2)

# Проверяем результат find_value (my_func, 2.0)

#Аргумента функции передана

#лямбда-функция

find_value (lambda х: х* (1 - х) , 0 . 5)

#Использование лямбда-функции

# в выражении

26

z=l+ (lamЬda х, у: х * у-х* *2) (2, 3 } * * 2

#Проверяем значение переменных print (" z =" , z)

В программном коде объявляется функция find value ( ) с двумя аргументами. Это самая обычная функция. Мы собираемся ее использовать как вспомогательную для иллюстрации к использованию лямбда-функций. Первый аргумент функции f, как предполагается, является ссылкой на функцию, а х – предполагаемый аргумент для этой функции. В теле функции find value ( ) командой print(" х = " , х , " -> f ( х ) =" , f ( х ) ) отображается сообщение, в котором, кроме прочего, использована инструкция f ( х ) вызова функции, на которую ссылается переменная f, с аргументом х.

Далее приведено несколько примеров описания и использования лямбда функций. Так, в команде my func=lambda х: 1 / (1 +х * * 2) есть описание лямбда-функции, а ссылка на эту функцию присваивается переменной my_func. Собственно, функция описывается инструкцией lambda х: 1 / (1 +х * * 2), в которой после ключевого слова lambda указано формальное название х для аргумента функции, а выражение 1 / (1+х**2) означает, что при аргументе функции х ее результатом будет значение 1/(1+х**2).

Чтобы проверить "работоспособность" созданной нами функции, используем команду find_value(my_func, 2.0). Б этой команде первым аргументом функции find_value() передается имя переменной my_func, которая содержит ссылку на лямбда-функцию. Второй аргумент 2.0 функции

find_value( ) – это значение аргумента для функции, на которую ссылается переменная my_func. В результате в консольное окно выводится со общение со значением my_func (2.0). Результатом является значение 0.2 (легко проверить, что f(2) = 1 +1 22 = 51 = 0.2). Еще один вариант, который мы рассматриваем - передача лямбда-функции в качестве аргумента функции. Соответствующая команда выглядит как find value (lambda х : х * ( 1 -х ) , 0.5 ) . Здесь первым аргументом функции find_value( ) передается не переменная со ссылкой на лямбда функцию, как в предыдущем случае, а сама лямбдафункция. Первый аргумент выглядит так: lambda х : х * ( 1 -х ). То есть аргументу функции x в соответствие ставится выражение х * (1-х) (это означает, что мы имеем дело с функцией f(x) = х · (1 - х)). Второй аргумент функции find_value( ) - числовое значение 0.5. Это значение играет роль аргумента для функции, переданной первым аргументом функции find _value( ). И хотя первым аргументом передана не переменная, а анонимная функция, суть дела не меняется: вычисляется значение f (0.5) = 0.5. (1 - 0.5) = 0.25 , то есть вычисленное значение равно 0.25.

Третий пример использования лямбда-функции: использование такой функции в выражении. Примером служит команда z = l + ( lambda х , у : х * уx* * 2 ) ( 2 , 3 ) * * 2 , в результате выполнения которой переменная z получает значение 5 . Значение выражения 1 + ( lambda х , у : х * у- х * * 2 ) ( 2 , 3 ) * * 2 вычисляется так: к единице прибавляется значение выражения ) lambda х , у :

27

х * у-х * * 2 ) ( 2 , 3 ) ' * * 2. Данное выражение – это квадрат А это выражение, значения выражения(1amЬdaх,у:х*у-х**2)(2,3) в свою очередь, есть не что

иное, как результат действия лямбда-функции (lambda

х, у :х * у-х * *2) на

аргументы (2,3 ). Инструкцией lambda х , у : х * у-х

* * 2 определяется

Лямбда-функция двух аргументов ( х и у), а результатом является значение х * у-х * * 2 , вычисляемое на основе значений аргументов функции. То есть здесь имеем дело с функцией f(x, y) =· ху - х2• Если вычислять значение этой функции для аргументов х = 2, у = 3 получим f (2,З) = 2 · З - 2 2 = 6 - 4 = 2 . Следовательно, значением выражения ( 1 ambda х , у : х * у-х * * 2 ) ( 2 , 3 ) является 2 , значением выражения ( 1 ambda х , у : х * у-х * * 2 ) _( 2 , 3 ) * * 2 является 4, а значение выражения 1+ ( lambda х·, у : х * у-х* * 2 ) ( 2 , 3 ) * * 2 , таким образом, 5.

В результате выполнения программы получаем такие сообщения в окне вывода:

х= 2 . 0 - > f ( х ) = 0 . 2

х=0. 5 - > f ( х ) = 0.25 z =5

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

Стоит отметить концептуально важный момент. Когда мы вызываем функцию (например, командой вида функция (аргументы), то сама инструкция вызова функции тоже является функцией. То есть выражение функция (аргументы) можно интерпретировать как имя функции (если точнее, то ссылку на функцию). Это ссылка именно на ту функцию, которая возвращается как результат вызываемой функции. Поэтому если после инструкции функция (аргументы) в круглых скобках указать аргументы, то получим вызов функциирезультата. Другими словами, при вызове функции-результата имеем дело с выражением вида функция(аргументы)(аргументы). Можно поступить иначе: присвоить некоторой переменной значение выражения функция(аргументы). После выполнения команды переменная = функция (аргументы) с переменной можно обращаться как с именем функции.

#Функция в качестве результата

#возвращает функцию

def my_pow ( n ) : return lambda х : x * * n

# Проверяем результат

for n in range ( l , 4 ) # Внешний цикл

for х in range ( l , 1 1 ) : # Внутренний цикл

# Выводим результат· вызова функции print (my_pow ( n ) ( х ) , end=" " )

print ( ) # Переходим к новой строке

28

В программном коде описывается функция my__pow ( ), у которой один аргумент n. Результатом функции возвращается инструкция lambda х : x * *n. Это лямбда-функция, у которой один аргумент х, а результат - значение аргумента х в степени n.

Для проверки работы созданной нами функции мы запускаем вложенные операторы цикла, в которых перебираем значения переменной n (от 1 до 3) и переменной х (от 1 до 10). Для каждой из пар значений командой print (my pow( n ) ( х ) , end=" ") выводятся (в одну строку – благодаря инструкции end= " ") значения выражения my_pow ( n ) ( х ). Результат выполнения программного кода представлен ниже:

1.2

3

4

5

6

7

8

9

10

1.4

9

16

25

36

49

64

81

 

100

1.8

27

64

125

216 343

512 729

1000

3.5. Локальные и глобальные переменные

Все параметры, указываемые в Python при объявлении и вызове функции, делятся на:

позиционные: указываются простым перечислением:

def function_name(a, b, c): # a, b, c - 3 позиционных параметра pass

ключевые: указываются перечислением ключ=значение:

def function_name(key=value, key2=value2): # key, key2 - 2 позиционных аргумента

pass # value, value2 - их значения по умолчанию

Позиционные и ключевые аргументы могут быть скомбинированы. Синтаксис объявления и вызова функции зависит от типа параметра, однако позиционные параметры (и соответствующие аргументы) всегда идут перед ключевыми:

-объявление функции:

def example_func(a, b, c):

# можно : 'a', 'b', 'c' - позиционные параметры

pass

 

 

def example_func(a, b, c=3):

# можно : 'a', 'b' - позиционные параметры,

pass

#

'c' - ключевой параметр

def example_func(a=1, b=2, c=3): # можно : 'a', 'b', 'c' - ключевые параметры pass

def example_func(a=1, с, b=2): # нельзя: ключевой параметр 'a' pass # идет раньше позиционнных

29

Источник: https://studfile.net/preview/16565614/