ComputerFellow
ComputerFellow

Reputation: 12108

Better way to call a chain of functions in python?

I have a chain of operations which needs to occur one after the other and each depends on the previous function's output.

Like this:

out1 = function1(initial_input)
out2 = function2(out1)
out3 = function3(out2)
out4 = function4(out3)

and so on about 10 times. It looks a little ugly in the code.

What is the best way to write it? Is there someway to handle it using some functional programming magic? Is there a better way to call and execute this function chain?

Upvotes: 6

Views: 3093

Answers (4)

Nicolas Barbey
Nicolas Barbey

Reputation: 6797

You can use functools.reduce:

out = functools.reduce(lambda x, y : y(x), [f1, f2, f3, f4], initial_value)

Quoting functools.reduce documentation:

Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.

Here, we use the fact that functions can be treated as any variable in Python, and an anonymous functions which simply does "apply x to function y".

This "reduce" operation is part of a very general pattern which have been applied successfully to parallelize tasks (see http://en.wikipedia.org/wiki/MapReduce).

Upvotes: 8

phipsgabler
phipsgabler

Reputation: 20950

To propagate functional programming a bit:

In [1]: compose = lambda f, g: lambda arg: f(g(arg))

In [2]: from functools import reduce

In [3]: funcs = [lambda x:x+1, lambda x:x*2]

In [4]: f = reduce(compose, funcs)

In [5]: f(1)
Out[5]: 3

In [6]: f(3)
Out[6]: 7

Upvotes: 2

jonrsharpe
jonrsharpe

Reputation: 122036

You can pass the return values directly to the next function:

out4 = function4(function3(function2(function1(initial_input))))

But this isn't necessarily better, and is perhaps less readable.

Upvotes: 1

falsetru
falsetru

Reputation: 369054

Use a loop:

out = initial_input
for func in [function1, function2, function3, function4]:
    out = func(out)

Upvotes: 5

Related Questions