我有一个做一些计算的函数g(x)。我现在想写一个计算 g(g(g(...g(x)))),其中 g 应用 n 次。我尝试使用repeat_fn
执行此操作(见下文),但这不起作用。
根据使用 lambda 表达式的递归函数,解决方案是使用 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))
当我使用k = repeat_fn(g, 5)
时repeat_fn
似乎只调用一次,而我希望它被调用五次。显然,递归直到我向 k 提供参数时才开始。print(k(2))
还给出了以下错误:TypeError: unsupported operand type(s) for *: 'int' and 'function'
。
这让我感到惊讶,因为例如h = g(g(x)
工作得很好。
谁能对此有所了解?谢谢!
使用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
如果你忽略函数应用程序,这要简单得多;它只是重复的函数组合:
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))
请注意,您也可以使用恒等函数identity = lambda x: x
为n==0
定义repeat_fn
:
def repeat_fn(f, n):
if n == 0:
return identity
else:
return compose(f, repeat_fn(f, n - 1))
这是因为compose(f, identity) == f
.