This is a question about programming style: what is the most "Pythonic" way to parameterize a function (is that even the right word for it?)
Say I have a function (e.g. an ODE solver) that accepts as an argument another function of two arguments (e.g. the ODE itself).
def solver(fun):
# Implementation goes here
# fun is a function handle that accepts two args e.g. fun(t,y)
However, the function I would like to pass into solver is parameterized by a third value
def myFun(t,y,A):
# Implementation goes here
I have been dealing with this situation using lambda functions as follows:
A = 4
solution = solver(lambda t,y:myFun(t,y,A))
I've recently been seeing some posts online telling me to avoid lambdas like the plague, and that Guido himself regrets allowing that feature. If lambdas are indeed terrible, what's the better "Pythonic" way to implement the above? Without lambda I run into the problem of being unable to access the global namespace, i.e. I want to do this:
A = 4
def myFunNotLambda(t,y):
return myFun(t,y,A)
solution = solver(myFunNotLambda)
but the only way to do this seems to be making A global, which is definitely far worse than using lambda
You can use functools.partial for that, like:
from functools import partial
A = 4
solution = solver(partial(myFun,A=A))
partial(..) constructs given a function (here myFunc) another function where the A parameter has now a default value with A.
Advice to "avoid lambda like the plague" is a serious exaggeration at best, and pure FUD at worst - grepping lambda in Python's standard library reveals literally thousands of matches.
While it is true that Guido has expressed later concern about lambda-dominated coding style, this was in context of (over)using functional constructs like map and reduce, which are better expressed in Python using list comprehensions and generator expressions.
When it comes to creating temporary functions like the one you need, however, there is exactly nothing wrong with using lambda; on the contrary, it's the best available tool for the job. If you still want to avoid lambda keyword, you can use a nested def:
def my_particular_fun(t, y):
return my_fun(t, y, 4)
solution = solver(my_particular_fun)
As presented in other answers, it is also possible to use functools.partial to emulate a lambda, although it comes at a cost of fixing the name of the third parameter to my_fun.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With