Ошибка рекурсии Python при умножении функций - PullRequest
0 голосов
/ 13 ноября 2018

Я использую Python 3 и пытаюсь умножить функции внутри цикла for. Я написал простой пример кода, чтобы продемонстрировать мою проблему. Я хочу, чтобы этот код начинал с функции x ^ 2, а затем умножил ее на x ^ 2 в первом цикле, чтобы получить x ^ 4. Затем умножьте x ^ 4 еще раз на x ^ 2, чтобы получить x ^ 6 т. Д.

fun = lambda x: x**2

function = lambda x: x**2
for i in range(2):
    function = lambda x: function(x) * fun(x)

print(function(2))

Но код выходит с ошибкой рекурсии. Я понятия не имею, как это вызывает рекурсию, хотя? Любая помощь будет высоко ценится.

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

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

def multiplyFun(fun1,fun2):
    fun = lambda x: fun1(x) * fun2(x)
    return fun


fun = lambda x: x**2

function = lambda x: x**2
for i in range(5):
    print(i)
    function = multiplyFun(function,fun)

print(function(2))
0 голосов
/ 13 ноября 2018

Альтернативный синтаксис: вместо того, чтобы передавать второй аргумент lambda, вы можете использовать вложенный lambda, где внешний вычисляется для возврата внутреннего:

squared = lambda x: x**2
function = lambda x: x**2

for i in range(2):
    function = (lambda f: lambda x: f(x) * squared(x))(function)

print(function(2))

Просто кажетсяболее общее решение (по языку), чем аргумент по умолчанию.

0 голосов
/ 13 ноября 2018

Назначение в вашем цикле эквивалентно:

def function(x):
    return function(x) * fun(x)

Это рекурсивная функция без условия остановки.Ваше первоначальное определение function затенено из-за правил связывания python :

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

Вы можете отследить это и проверить такое поведение, используя python3 -m trace --trace script.py:

--- modulename: script, funcname: <lambda>
script.py(6):     function = lambda x: function(x) * fun(x)
--- modulename: script, funcname: <lambda>
script.py(6):     function = lambda x: function(x) * fun(x)

# Repeated until a RecursionError is thrown

Вместо этого вы можете связать свою функцию какаргумент лямбды:

fun = lambda x: x**2
function = lambda x: x**2
for i in range(2):
    function = lambda x, y=function: y(x) * fun(x)

print(function(2))

, который произведет следующий след:

--- modulename: script, funcname: <module>
script.py(3): fun = lambda x: x**2
script.py(4): function = lambda x: x**2
script.py(5): for i in range(2):
script.py(6):     function = lambda x, y=function: y(x) * fun(x)
script.py(5): for i in range(2):
script.py(6):     function = lambda x, y=function: y(x) * fun(x)
script.py(5): for i in range(2):
script.py(8): print(function(2))
--- modulename: script, funcname: <lambda>
script.py(6):     function = lambda x, y=function: y(x) * fun(x)
--- modulename: script, funcname: <lambda>
script.py(6):     function = lambda x, y=function: y(x) * fun(x)
--- modulename: script, funcname: <lambda>
script.py(4): function = lambda x: x**2
--- modulename: script, funcname: <lambda>
script.py(3): fun = lambda x: x**2
--- modulename: script, funcname: <lambda>
script.py(3): fun = lambda x: x**2
64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...