1

I'm using python 3 and trying to multiply functions within a for loop. I wrote a simple example code to demonstrate my problem. What I want this code to do was to start with the funciton x^2, then multiply it by x^2 in first loop, to get x^4. Then multiply x^4 again with x^2 to get x^6 e.t.c.

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))

But the code comes out with a Recursion error. I have no idea how this is causing a recursion though? Any help will be much appreciated.

3 Answers 3

1

The assignment in your loop is equivalent to:

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

Which is a recursive function without a stop condition. Your initial definition of function is shadowed, due to python's binding rules:

The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block)

You can trace it and verify such behaviour using 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

You can instead bind your function as an argument of the lambda:

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))

Which will produce the following trace:

--- 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
Sign up to request clarification or add additional context in comments.

1 Comment

Oh haha I just wrote this workout myself, crazy timing. Thank you for the explanation though!
0

I never found a solution to this, but did find a workaround. Rather than trying to multiply it straight away, I wrote a function to do the multiplication. This seems to works so I'll just use this instead.

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))

Comments

0

An alternate syntax: rather than pass a second argument to the lambda, you can use a nested lambda where the outer one is evaulated to return the inner one:

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))

Just seems more generic solution (language-wise) than a defaulted argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.