How to package a sequence functions that act on parameter in order in Python

225 Views Asked by At

Imagine there are three functions, all them accept and return the same type args.

Normally, we can write it as fun3(fun2(fun1(args)), this can be say that a sequence function act on parameter in order, which likes one variety Higher-order functions "map".

You know in Mathematica, we can write this as fun3@fun2@fun1@args.

Now the question is that can we integrate fun3@fun2@fun1 as another fun without modifying their definition, so fun(args) can replace fun3(fun2(fun1(args)), this looks more elegant and concise.

3

There are 3 best solutions below

1
woody On BEST ANSWER
def merge_steps(*fun_list):
    def fun(arg):
        result = arg
        for f in fun_list:
            result = f(result)
        return result

    return fun


def plus_one(arg):
    return arg + 1


def double_it(arg):
    return arg ** 2


def power_ten(arg):
    return arg ** 10


combine1 = merge_steps(power_ten, plus_one, double_it)
combine2 = merge_steps(plus_one, power_ten, double_it)

combine1(3) 
> 3486902500

or use lambda:

steps = [power_ten, plus_one, double_it]

reduce(lambda a, f: f(a), steps, 3)
> 3486902500
1
EdKenbers On

I think you can use Function Recursion in python to do this.

def function(args, times):
    print(f"{times} Times - {args}")
    if times > 0 : 
        function(args,times - 1)

function("test", 2)

Note: I just add times argument to not generate infinite loop.

3
FMc On

I'm not certain I understand your question, but are you talking about function composition along these lines?

# Some single-argument functions to experiment with.

def double(x):
    return 2 * x

def reciprocal(x):
    return 1 / x

# Returns a new function that will execute multiple single-argument functions in order.

def compose(*funcs):
    def g(x):
        for f in funcs:
            x = f(x)
        return x
    return g

# Demo.

double_recip_abs = compose(double, reciprocal, abs)
print(double_recip_abs(-2))   # 0.25
print(double_recip_abs(.1))   # 5.0