Reputation:
I know that sympy’s lambdify
function can create a lambda with arguments variables
and body expression
like this:
lambdify(variables, expression)
so
lambdify((Symbol('x'), Symbol('y')) , 'x**2 + y')
produces
lambda x, y: x**2 + y
But how do I give default values to some of the variables? To get something like
lambda x, y=0: x**2 + y
?
I know I can do this with strings like lambdify(('x', 'y=0') , 'x**2 + y')
, but I need to work with sympy symbol objects, since I’m extracting them from other sympy expressions.
Upvotes: 3
Views: 910
Reputation: 91620
The fact that it works with strings is an accident. The way lambdify works is it creates a string form of the expression, then evals the string "lambda %s: (%s)" % (', '.join(map(str, args)), expr)
(it's actually a little more complicated than that in general, but that's the basic idea). So if args is ('x', 'y=0')
, that ends up being inserted as lambda x, y=0: ...
.
Right now lambdify
doesn't have an option to make the parameters keyword arguments, so your best options are:
Create keyword arguments manually using strings (what you already discovered works), or
Wrap the lambdified function in a new lambda, like
lambda x, y=0: lambdify((x, y), expr)(x, y)
To do it in the general case, you can write some function that creates a keyword argument wrapper with whatever logic you want, like
from functools import wraps
def create_wrapped(args, expr):
func = lambdify(args, expr)
@wraps(func)
def wrapped(*_args, **kwargs):
# Write the logic here to parse _args and kwargs for the arguments as you want them
return func(*actual_args)
return wrapped
Upvotes: 1