Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a function that uses the value of a variable? [duplicate]

I want to write a function which returns a list of functions. As a MWE, here's my attempt at function that gives three functions that add 0, 1, and 2 to an input number:

def foo():
    result = []
    for i in range(3):
        temp = lambda x: x + i
        print(temp(42))  # prints 42, 43, 44
        result.append(temp)
    return result

for f in foo():
    print(f(42))  #prints 44, 44, 44

Contrary to my expectation, each function ends up using the last value taken by i. I've experienced similar behavior when e.g. a list is used as argument to a function but Python actually uses a pointer to the list, but here i is an integer, so I don't understand what's going on here. I'm running Python 3.5.

like image 631
bjarkemoensted Avatar asked Feb 02 '17 13:02

bjarkemoensted


People also ask

Can we return 2 variables?

You cannot explicitly return two variables from a single function, but there are various ways you could concatenate the two variables in order to return them.

How do you use a variable returned from a function?

To return a value from a function, you must include a return statement, followed by the value to be returned, before the function's end statement. If you do not include a return statement or if you do not specify a value after the keyword return, the value returned by the function is unpredictable.

How do you return two variables in a function?

We can return more than one values from a function by using the method called “call by address”, or “call by reference”. In the invoker function, we will use two variables to store the results, and the function will take pointer type data. So we have to pass the address of the data.

Can the function return a value using the keyword return?

The return keyword in C++ returns a value to a function. The return keyword is declared inside a function to return a value from the given function.


1 Answers

Closures bind late, meaning they will use the last value of i in the scope they have been defined when called (in this case the last value of i will be 2).

The common solution to this is providing the value of i as a default argument:

temp = lambda x, i=i: x + i

Since Python evaluates default arguments during the construction of a function, this is a trick that helps Python use the correct value of i when the callable is invoked, it doesn't create a closure and, instead, can look i up in it's locals.

like image 72
Dimitris Fasarakis Hilliard Avatar answered Oct 07 '22 21:10

Dimitris Fasarakis Hilliard