功能制作

时间:2012-09-14 16:34:05

标签: python functional-programming

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

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

现在,它没有创建g作为非终止递归函数 - g(x)被转换为一个新函数,它给出了结果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))....)))进行一定数量的迭代?

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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

答案 2 :(得分: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的值。