0

I want to update a python lambda function for several times, e.g.,

f = lambda x: 0
for t in range(10):
    g_t = .... # some function independent of f
    f = lambda x: f(x) + g_t(x) # update f for 10 times

calling f gives me:

...

File "<stdin>", line 3, in <lambda>

File "<stdin>", line 3, in <lambda>

...

File "<stdin>", line 3, in <lambda>

RuntimeError: maximum recursion depth exceeded

Anyway to get around this?

2
  • 1
    What is the actual task you're trying to solve? Commented Mar 5, 2017 at 7:52
  • 2
    This code alone can't cause stack overflow because you never invoke the function. Please provide all of the code necessary to reproduce the error you're describing Commented Mar 5, 2017 at 7:52

1 Answer 1

4

If you invoke f after the snippet you've pasted, you'll get unbounded recursion, and will eventually exceed the maximum stack depth.

This is because Python closures are captured lexically, meaning they point at the variable name in scope, not the specific value of the variable at the point in time when the lambda is created. When the final value of f is invoked, the f(x) expression will recursively invoke the final value of f, not the value from the previous iteration.

The workaround is to pass the current value of f as an argument to the new lambda you are creating, instead of closing over it:

f = lambda x: 0
for t in range(10):
    g_t = lambda x: 1 # some function independent of f
    f = lambda x, curr_f=f: curr_f(x) + g_t(x) # pass f as a default argument to the lambda
print(f(0)) # prints 10, no stack overflow
Sign up to request clarification or add additional context in comments.

3 Comments

Excellent answer! The line f = lambda x, f=f: f(x) + g_t(x) is cryptic yet pythonic! :P
@varun Sorry, didn't intend for that to be cryptic. I've simply added an extra argument named f to the lambda, and immediately passed the variable f as its default value.
It's pythonic although it is cryptic. I meant that as a compliment! One might have to read through that statement a couple of times before understanding it. That's a clever way of using default parameter as a function :)

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.