简体   繁体   English

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

[英]Recursive function using lambda's, why does this not work?

I have a function that does some calculation, g(x). 我有一个函数做一些计算,g(x)。 I now want to write a function that calculates g(g(g(...g(x)))), where g is applied n times. 我现在想写一个计算g(g(g(... g(x))))的函数,其中g被应用n次。 I tried to do this using repeat_fn (see below), but this does not work. 我尝试使用repeat_fn (见下文)这样做,但这不起作用。

According to Recursive function using lambda expression the solution is to use functools.partial. 根据使用lambda表达式递归函数 ,解决方案是使用functools.partial。 This does indeed work, but I do not understand how. 这确实有效,但我不明白怎么做。 Also, I do not understand why my approach doesn't work. 另外,我不明白为什么我的方法不起作用。

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))

It appears repeat_fn is only called once when i use k = repeat_fn(g, 5) , while I would expect it to be called five times. 看来repeat_fn仅在我使用k = repeat_fn(g, 5)时被调用一次,而我希望它被调用五次。 Apparently, the recursion doesn't start until I supply k with an argument. 显然,在我用参数提供k之前,递归才会开始。 Also print(k(2)) gives the following error: TypeError: unsupported operand type(s) for *: 'int' and 'function' . print(k(2))给出以下错误: TypeError: unsupported operand type(s) for *: 'int' and 'function'

This surprised me, because eg h = g(g(x) works just fine. 这让我感到惊讶,因为例如h = g(g(x)效果很好。

Can anyone shed some light on this? 任何人都可以对此有所了解吗? Thanks! 谢谢!

With return lambda y: f( repeat_fn(f(y), n-1) ) , you are calling repeat_fn with the f parameter being the result of f(y) , ie not a function. 使用return lambda y: f( repeat_fn(f(y), n-1) ) ,您调用repeat_fn ,其中f参数是f(y)的结果,即不是函数。 Instead, you should pass just f and then apply the result of fn_repeat (a function) to f(y) (or vice versa). 相反,您应该只传递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

This is a lot simpler if you ignore function application; 如果忽略函数应用程序,这会简单得多; it's just repeated function composition : 它只是重复的功能组成

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))

Note that you can define repeat_fn for n==0 as well, using the identity function identity = lambda x: x : 请注意,您也可以使用identity函数identity = lambda x: xn==0定义repeat_fn

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

This is because compose(f, identity) == f . 这是因为compose(f, identity) == f

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM