Thomas Produit
Thomas Produit

Reputation: 113

List defining the list of variable of function in Python

I want to have a function foo which outputs another function, whose list of variables depends on an input list.

Precisely:

Suppose func is a function with the free variable t and three parameters A,gamma,x

Example: func = lambda t,A,gamma,x: Somefunction

I want to define a function foo, which takes as input a list and outputs another function. The output function is a sum of func's, where each func summand has his parameters independent from each other.

Depending on the input list the variables of the outputs changes in the following:

If the entry of the list is 'None' then the output function 'gains' a variable and if the entry of the list is a float it 'fixes' the parameter.

Example:

li=[None,None,0.1]
g=foo(li)

gives the same output as

g = lambda t,A,gamma: func(t,A,gamma,0.1)

or

li=[None,None,0.1,None,0.2,0.3]
g=foo(li)

gives the same output as

g = lambda t,A1,gamma1,A2:func(t,A,gamma,0.1)+func(t,A2,0.2,0.3)

Note: the order in the list is relevant and this behaviour is wanted.

I don't have any clue on how to do that...

I first tried to build a string, which depends on the inout list and then to execute it, but this is surely not the way.

Upvotes: 1

Views: 1981

Answers (1)

tobias_k
tobias_k

Reputation: 82889

First, partition the parameters from li into chunks. Then use an iterator to either get the next from the function parameters *args, if the value in that chunk is None, or the provided value from the parameters chunk.

def foo(li, func, num_params):
    chunks = (li[i:i+num_params] for i in range(0, len(li), num_params))
    def function(t, *args):
        result = 0
        iter_args = iter(args)
        for chunk in chunks:
            actual_params = [next(iter_args) if x is None else x for x in chunk]
            result += func(t, *actual_params)
        return result
    return function

Example:

def f(t, a, b, c):
    print t, a, b, c
    return a + b + c

func = foo([1,2,None,4,None,6], f, 3)
print func("foo", 3, 5)

Output:

foo 1 2 3  # from first call to f
foo 4 5 6  # from second call to f
21         # result of func

Upvotes: 2

Related Questions