2

Say that I have a list of functions: [f1, f2, f3] (in python)

How do I return a single function F:=f3(f2(f1())) (notice that F is of function type). I know that it's possible to do it with .reduce() but I was wondering if there's another way to do it without using libraries.

edit:

Also, notice that the length of the list can be greater than 3

I tried:

def func(list):
  i = 1
  new_function = filters[0]
  while i<=len(filters)-1:
      new_function = filters[i](new_function)
      i+=1
  return new_function

but it doesn't work

6
  • Where did you start with this problem? Did you manage to write any code for it? Commented Sep 18, 2021 at 20:46
  • reduce is part of the Python Standard Library and has a rough equivalent available for use in the docs. Commented Sep 18, 2021 at 20:46
  • 2
    f = lambda x: f3(f2(f1(x))) Commented Sep 18, 2021 at 20:46
  • def func(List): i = 1 new_function = filters[0] while i<=len(filters)-1: new_function = filters[i](new_function) i+=1 return new_function I tried this by it doesn't work Commented Sep 18, 2021 at 20:47
  • 1
    You can edit your question to add more information @Onini Commented Sep 18, 2021 at 20:48

3 Answers 3

3

The problem in your code is that you pass a function as argument with filters[i](new_function).

I would suggest this recursive solution:

def chain(first, *rest):
    return lambda x: first(chain(*rest)(x) if rest else x) 

Example use:

def inc(x):
    return x + 1

def double(x):
    return x * 2

def square(x):
    return x * x

f = chain(square, double, inc)

print(f(5))  # ((5+1)*2) ** 2 == 144
Sign up to request clarification or add additional context in comments.

Comments

0

I see that in the code you tried, you never actually call the first of your functions. (I also assume that your code starts: def func(filters):

Taking into account that f1() takes no parameter, but the rest take the parameter of the return of the previous function, this should work:

def fit(funcs):
    v = funcs[0]()
    for f in funcs[1:]:
        v = f(v)
    return v

def f1():
    return 42

def f2(x):
    return x

def f3(x):
    return x

fs = [f1, f2, f3]

a = lambda:fit(fs)

print(a())

Output: 42

Comments

0
def get_single_func(func_list):
    def single_func(*args, **kwargs):
        ret = func_list[0](*args, **kwargs)
        for func in func_list[1:]:
            ret = func(ret)
        return ret
    return single_func

        

2 Comments

OK after thinking about the problem for a little bit I came up with my own solution. I'm still quite interested in this one. can you explain what (*args, **kwargs) is doing in func_list[0](*args, **kwargs)?
The operators * and ** are called "unpacking operators". The first one converts a list into a sequence of values and the second one converts a dictionary into a sequence of key/values. One very frequent use of the unpacking operators is to define a function that can accept any positional and named parameters. That is what I did, because I don't know in advance what the first function in the chain will be, so I have to be prepared to accept any parameters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.