Is it possible to create a function which takes lambda functions as arguments (with each lambda function using argument x
) and then returns a new function which has a single argument x
and returns the product of all the lambda functions?
Here's my non-working example:
def func_you( lambdafunc1, lambdafunc2, lambdafunc3, lambdafunc4):
return def func_you_2(x):
return lambdafunc1(x) * lambdafunc2(x) * lambdafunc3(x) * lambdafunc4(x)
So essentially what happens is you have a function func_you
which takes 4 lambda functions each using argument x
. As an example, the argument for lambdafunc1
could be something like lambda x: x + 10
.
func_you
then returns a new function called func_you_2
whose output is the product of all those lambda functions and has one argument x
which is passed onto the x
argument of each of func_you
's lambda functions.
Assuming what I'm trying to do is possible, how do I convey the proper syntax to do it?
Also, is there a specific name for this kind of thing rather than "function that returns a function"? It's technically not a nested function, right?
My answer is no better than any other answer so far, but I wanted to tweak it a bit to squeeze a little more functional-programming-juice out of the question, just for fun.
from functools import reduce
from operator import mul
def functioners(*funcs):
def inner(x):
return reduce(mul, [f(x) for f in funcs], 1)
return inner
In [2]: res = functioners(lambda x: x+1, lambda x: x *2, lambda x: x+3)
In [3]: res(5)
Out[3]: 480
In [4]: res = functioners(lambda x: x+1, lambda x: x +1, lambda x: x+1)
In [5]: res(1)
Out[5]: 8
Edit
I even got a little crazier with it in order to implement a kind-of 10-minute currying attempt. This is not something I would ever subject my coworkers to, but it's late where I am so maybe just for fun...
It should be possible to define a function that can keep returning a partially applied version of itself, but I guess you need some way to tell it to stop?
Here's my attempt:
from functools import partial, reduce
from operator import mul
def functionals(*funcs, finished=None):
def inner(x):
return reduce(mul, [f(x) for f in funcs], 1)
if finished is not None:
# stop condition
return inner
else:
return partial(functionals, *funcs)
You could use it like this (if you were so inclined...)
In [37]: f1 = functionals(lambda x: x+1)
In [38]: f2 = f1(lambda x: x + 1)
In [39]: f3 = f2(lambda x: x + 1, lambda x: x + 1, lambda x: x + 1)
In [40]: f3(finished="definitely!")(1)
Out[40]: 32
(I will get my hat and coat now...)
You can return a lambda function that does what you want. Example -
def func_you( lambdafunc1, lambdafunc2, lambdafunc3, lambdafunc4):
return lambda x: lambdafunc1(x) * lambdafunc2(x) * lambdafunc3(x) * lambdafunc4(x)
Demo -
>>> def func_you( lambdafunc1, lambdafunc2, lambdafunc3, lambdafunc4):
... return lambda x: lambdafunc1(x) * lambdafunc2(x) * lambdafunc3(x) * lambdafunc4(x)
...
>>> f = func_you(sum,min,max,sum)
>>> f([1,2])
18
This is definitely technically a nested function:
def func_you(lambdafunc1, lambdafunc2, lambdafunc3, lambdafunc4):
def func_you_2(x):
return lambdafunc1(x) * lambdafunc2(x) * lambdafunc3(x) * lambdafunc4(x)
return func_you_2
But you could use a lambda
too:
def func_you(lambdafunc1, lambdafunc2, lambdafunc3, lambdafunc4):
return lambda x: lambdafunc1(x) * lambdafunc2(x) * lambdafunc3(x) * lambdafunc4(x)
The def
-within- def
structure is actually quite common. It's used to implement decorator functions , which take a function as an input, modify it somehow, and return the modified function. Basically, this structure:
@decorator
def func(param):
# stuff
is the same as:
def func(param):
# stuff
func = decorator(func)
For example, say you have several functions which you want to modify so that they print messages on entry and exit. You write a decorator function:
def mark_entry_and_exit(func):
def inner(*args, **kwargs):
print "Entering function."
try:
result = func(*args, **kwargs)
except:
print "Exiting with exception."
raise
print "Exiting function."
return result
return inner
Then to use it, you just use the @
notation above:
@mark_entry_and_exit
def my_function(a, b):
print "Running with", a, b
my_function(1, b=2)
prints:
Entering function.
Running with 1 2
Exiting function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.