I have a set of functions f(x), g(x), s(x), t(x).
They are designed to be chained together like this: f(g(s(t(x))))
The functions are designed so they can be chained in any sequence. Another part of my code builds the sequence in a list: [f, g, s, t]
Is there an elegant way to take the list and chain the function calls, getting the output of the last result?
Now obviously I can do it using an outside counter-like variable which tracks the output and a simple for loop increment index, but I was wondering if there is an more Pythonic way to do this?
Reduce is the perfect answer (though we need to start with the innermost function, thus reversed):
import functools
functions = [f, g, s, t]
y = functools.reduce(lambda a, f: f(a), reversed(functions), x)
EDIT: With constant parameters, as easy as this:
p1, p2 = 5, 42
y = functools.reduce(lambda a, f: f(a, p1, p2), reversed(functions), x)
Martineau and Amadan already posted the "elegant" solution. Now the truly pythonic solution is as stupid, simple an plain boring as it can get:
def chain(arg, *funcs):
# chain(42, f, g, s) => f(g(s(42)))
result = arg
for func in reversed(funcs):
result = func(result)
return result
It's clearly not what most people would consider "elegant", but it's perfectly obvious, readable, and is very easy to trace and debug - and that's what matters most wrt/ python's philosophy.
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