2

There are lots of interesting posts on this subject, but I seem to either not understand their answers, or aiming for something different. Here is what I am trying to do. I have two (or more) functions that I want to combine into a new function. The following snippet shows what I start with, and what I would like to end up with.

def a(x):
    0.2 * x[1] - 0.4 * x[0]

def b(x):
    0.4 * x[0] - 0.2 * x[1]

def ab(x):
    return [0.2 * x[1] - 0.4 * x[0], 0.4 * x[0] - 0.2 * x[1]]

the catch being, that I would like to create ab at run time dynamically. I have a list ml with all functions so I could do the following inside a new function

def abl(x):
    ml = [a, b]
    rl = []
    i = 0
    for f in ml:
        rl.append(f(x[i]))
        i = i + 1 

and then call abl. This code combines the individual functions and results in the expected output. However, for each call to abl rl has to be built anew, which seems wasteful.

Is there another way of combining a and b in order to create a new function ab?

8
  • I didn't get it. What's the problem of ab(x) ? Commented Dec 3, 2021 at 17:16
  • 1
    The code you have posted for abl doesn't seems complete. Please provide a complete, reproducible example. Commented Dec 3, 2021 at 17:16
  • have you tried eval docs.python.org/3/library/functions.html#eval Commented Dec 3, 2021 at 17:16
  • You don't need an i. More pythonic to do for f, xi in zip(ml, x) and use xi instead of x[i]. Actually you don't need this at all, since you want to pass the entire x to both a() and b() functions. Just do for f in ml: rl.append(f(x)) Commented Dec 3, 2021 at 17:19
  • Also, you'd create a new rl every time you call ab() anyway - creating it the way you do in abl() is no different from creating it the way you do in ab() Commented Dec 3, 2021 at 17:20

2 Answers 2

7

You can dynamically return new functions via lambda expressions:

def a(x):
    return 0.2 * x[1] - 0.4 * x[0]

def b(x):
    return 0.4 * x[0] - 0.2 * x[1]

def combine(func1, func2):
    return lambda x: [func1(x), func2(x)]
    
ab = combine(a, b)
print(ab([1.3, 2.9]))

Output:

[0.05999999999999994, -0.05999999999999994]
Sign up to request clarification or add additional context in comments.

Comments

3

You can extend @Random Davis's lambda approach to any number of functions using *args:

def a(x):
    return 0.2 * x[1] - 0.4 * x[0]

def b(x):
    return 0.4 * x[0] - 0.2 * x[1]

def c(x):
    return 0.5 * x[0]

def d(x):
    return 0.5 * x[1]

def combine(*args):
    return lambda x: [f(x) for f in args]

abcd = combine(a, b, c, d)
print(abcd([1.3, 2.9]))

gives

[0.05999999999999994, -0.05999999999999994, 0.65, 1.45]

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.