使用lambda的递归函数,为什么这不起作用?

时间:2018-02-08 13:53:20

标签: python recursion lambda

我有一个函数可以进行一些计算,g(x)。我现在想写一个计算g(g(g(... g(x))))的函数,其中g被应用n次。我尝试使用repeat_fn(见下文)执行此操作,但这不起作用。

根据Recursive function using lambda expression,解决方法是使用functools.partial。这确实有效,但我不明白怎么做。另外,我不明白为什么我的方法不起作用。

g = lambda x: 2*x

# Function that returns the fˆn map
def repeat_fn(f, n):
     if n == 1:
         return f
    else:
        return lambda y: f( repeat_fn(f(y), n-1) )


 def repeat_fn_base(fn, n, x):
    if n == 1:
        return fn(x)
    else:
        return fn(repeat_fn_base(fn, n-1, x))

def repeat_fn2(fn, n):
    return functools.partial(repeat_fn_base, fn, n)


j = repeat_fn2(g, 5)
print(type(j))
print(j(2))

k = repeat_fn(g, 5)
print(type(k))
print(k(2))

当我使用repeat_fn时,k = repeat_fn(g, 5)只会被调用一次,而我希望它会被调用五次。显然,递归直到我用参数提供k才开始。另外,print(k(2))会出现以下错误:TypeError: unsupported operand type(s) for *: 'int' and 'function'

这令我感到惊讶,因为例如h = g(g(x)工作正常。

有人可以对此有所了解吗?谢谢!

2 个答案:

答案 0 :(得分:5)

使用return lambda y: f( repeat_fn(f(y), n-1) ),您调用的repeat_fn f参数是f(y)的结果,即不是一个函数。相反,您应该只传递f,然后将fn_repeat(函数)的结果应用于f(y)(反之亦然)。

def repeat_fn(f, n):
    if n == 1:
         return f
    else:
        return lambda y: repeat_fn(f, n-1)(f(y))

k = repeat_fn(lambda x: 2*x, 5)
print(k(2))  # 64

答案 1 :(得分:2)

如果忽略函数应用程序,这会简单得多;它只是重复功能组成

def compose(f, g):
    return lambda x: f(g(x))

def repeat_fn(f, n):
    if n == 1:
        return f
    else:
        return compose(f, repeat_fn(f, n - 1))

请注意,您也可以使用身份函数repeat_fnn==0定义identity = lambda x: x

def repeat_fn(f, n):
    if n == 0:
        return identity
    else:
        return compose(f, repeat_fn(f, n - 1))

这是因为compose(f, identity) == f