How to compose a nested function g=fn(...(f3(f2(f1()))...) from a list of functions [f1, f2, f3,...fn]

One way using functools.reduce:

from functools import reduce

f1 = lambda x: x+1
f2 = lambda x: x*2
f3 = lambda x: x+3
funcs = [f1, f2, f3]

g = reduce(lambda f, g: lambda x: g(f(x)), funcs)

Output:

g(1)==7 # ((1+1) * 2) + 3
g(2)==9 # ((2+1) * 2) + 3

Insight:

functools.reduce will chain its second argument (funcs here) according to its first argument (lambda here).

That being said, it will start chaining f1 and f2 as f_21(x) = f2(f1(x)), then f3 and f_21 as f3(f_21(x)) which becomes g(x).


One problem with the reduce-baed approach is that you introduce O(n) additional function calls. An alternative is to define a single function that remembers the functions to compose; when called, it simply calls each function in sequence on the given argument.

def compose(*args):
    """compose(f1, f2, ..., fn) == lambda x: fn(...(f2(f1(x))...)"""

    def _(x):
        result = x
        for f in args:
            result = f(result)
        return result
    return _

You can implement it yourself, but you could also try a module named compose which implements this, written by @mtraceur. It takes care to handle various details, such as correct function signature forwarding.

pip install compose
from compose import compose

def doubled(x):
    return 2*x

octupled = compose(doubled, doubled, doubled)

print(octupled(1))
# 8

Tags:

Python