我正在尝试编写一个组成任意数量lambda函数的函数。
我有两个简单的lambda函数。
f = lambda x: x + 1
g = lambda x: x**2
我对作曲功能的尝试是这样的:
def compose(*functions):
composed = lambda x: x # Function that returns input
for function in reversed(functions):
composed = lambda x: function(composed(x))
return composed
我的想法是遍历可变数量的函数,每次使composed
函数包含一个新函数。
然后我可以创建一个由f
和g
c = compose(f, g)
所以调用c(5)
应该返回f(g(5))
,即26。但相反,我得到了
RecursionError: maximum recursion depth exceeded
我认为引入中间变量可能会解决问题。
def compose(*functions):
composed = lambda x: x # Function that returns input
for function in reversed(functions):
intermediate = lambda x: function(composed(x))
composed = intermediate
return composed
但提出同样的错误。
有没有办法解决这个问题?
答案 0 :(得分:2)
首先,我认为你的方法将受到后期闭包绑定的影响,因为lambda中的function
只会在迭代结束时获取函数的最后一个值。其次,由于第一个原因,composed
最终也只能递归地调用自己; composed
- lambda - 调用composed
的最后一个值 - 本身!
一种可能的解决方法是在每次迭代时将composed
和function
绑定到lambda
:
def compose(*functions):
composed = lambda x: x
for function in reversed(functions):
composed = lambda x, function=function, composed=composed: function(composed(x))
return composed
print(compose(f, g)(5))
# 26
但是您的整体问题看起来像是functools.reduce
的一个很好的用例:
from functools import reduce
def compose(*functions):
def inner(v):
return reduce(lambda x, y: y(x), reversed(functions), v)
return inner
print(compose(f, g)(5))
# 26