1

So i have

x = 3 

def first(x):
    return x+2

def second(x):
    return x/2

def third(x):
    return x*4

I would like to make a pipe of functions like :

first -> second -> third

but all combinations of functions : like first -> second , first -> third

and get each time the value of x for each combination.

And i don't need not only to multiply them but to be able to make multiple combination of various length.

Here it's just fixed number of combination : How to multiply functions in python?

regards and thanks

Bussiere
  • 500
  • 13
  • 60
  • 119

1 Answers1

2

First the combinations part:

>>> functions = [first, second, third]
>>> from itertools import combinations, permutations
>>> for n in range(len(functions)):
...     for comb in combinations(functions, n + 1):
...         for perm in permutations(comb, len(comb)):
...             print('_'.join(f.__name__ for f in perm))
...             
first
second
third
first_second
second_first
first_third
third_first
second_third
third_second
first_second_third
first_third_second
second_first_third
second_third_first
third_first_second
third_second_first

Next the composing part, steal the @Composable decorator from the question How to multiply functions in python? and use it to compose functions from each permutation.

from operator import mul
from functools import reduce
for n in range(len(functions)):
    for comb in combinations(functions, n + 1):
        for perm in permutations(comb, len(comb)):
            func_name = '_'.join(f.__name__ for f in perm)
            func = reduce(mul, [Composable(f) for f in perm])
            d[func_name] = func

Now you have a namespace of functions (actually callable classes), demo:

>>> f = d['third_first_second']
>>> f(123)
254.0
>>> third(first(second(123)))
254.0
>>> ((123 / 2) + 2) * 4
254.0
wim
  • 338,267
  • 99
  • 616
  • 750