4

嗨,我是函数式编程的新手。我所做的是

>>> g=lambda x:x*2
>>> f=g
>>> g=lambda x:f(f(x))
>>> g(9)
36

现在,它不是g作为非终止递归函数创建的 -g(x)被转换为一个新函数,它给出了 result g(g(x))

>>> f=g
>>> g=lambda x:f(f(x))
>>> f(8)
RuntimeError: maximum recursion depth exceeded

根据 g(x) 的第一个定义,我希望g被转换成一个给出结果的函数。g(g(g(x)))为什么不呢?是否有可能以这种方式创建一个导致g(g(g(...(g(x))....)))一定次数迭代的新函数?

4

3 回答 3

6

当你f = g第二次这样做时, f 变为lambda x: f(x)。闭包是按名称创建的,而不是按值创建的。


借助辅助函数,这变得很容易:

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

square = lambda x:x*2
g = square
for i in xrange(4):
    g = compose(g, square)
于 2012-09-14T16:37:51.510 回答
4

在 python 中,变量是映射到值的名称,而不是值本身(一切都是引用)。此外,您可以将 lambda 视为存储可以评估的文本。下面将说明

a = 2
f = lambda x: a*x
f(2) # This gives 4
a = 3
f(2) # This gives 6

这应该清楚为什么你会得到无限递归。

在回答你关于递归的问题时,这里有一个小技巧可以做

g = lambda x, n: n > 0 and g(x, n-1)**2 or x

那么g(2,3)将是(((2)^2)^2)^2 = 256.

于 2012-09-14T16:50:20.597 回答
2

g=lambda x:x*2
f=g
g=lambda x:f(x)

相当于:

f=lambda x:x*2
g=lambda x:f(x)

当您调用 时g,您会得到f在全局(或封闭)范围内定义的任何内容。

你期待的是这样的:

f=lambda x:x*2
g=lambda x, f=f:f(x)

lambda 这会在计算表达式时捕获外部范围内的 f值。

于 2012-09-14T16:57:59.187 回答