【问题标题】:RecursionError composing lambdasRecursionError 组合 lambdas
【发布时间】:2016-11-10 00:58:21
【问题描述】:

我正在尝试编写一个包含任意数量的 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 函数在其中包含一个新函数。

然后我可以创建一个由fg 组成的函数

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

但同样的错误也出现了。

有没有办法解决这个问题?

【问题讨论】:

    标签: python python-3.x recursion lambda


    【解决方案1】:

    首先,我认为您的方法会受到后期闭包绑定的影响,因为 lambda 中的function 只会在迭代结束时获取函数的最后一个值。其次,composed 最终只会递归调用自己,也是由于第一个原因; composed - lambda - 调用 composed 的最后一个值 - 本身!

    一种可能的解决方法是在每次迭代时将composedfunction 绑定到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
    

    【讨论】:

    • 很好的解决方案,但你能发现 OP 尝试中的错误吗?
    • @juanpa.arrivillaga 看看
    • 是的,刚刚发现这是由于后期绑定造成的。
    猜你喜欢
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2021-04-14
    • 2012-08-27
    • 2023-04-02
    • 2019-11-23
    相关资源
    最近更新 更多