python返回值为函数的一个题
def double(f):
print(f)
return (lambda x: (f(f(x))))
def inc(x):
return x+1
print(double(inc)(0))
print((double(double))(inc)(0))
print((double(double(double)))(inc)(0))
结果为:
<function inc at 0x00000000029BBB70>
2
<function double at 0x0000000002141730>
<function inc at 0x00000000029BBB70>
<function double.<locals>.<lambda> at 0x00000000029BBC80>
4
<function double at 0x0000000002141730>
<function double.<locals>.<lambda> at 0x00000000029BBD08>
<function inc at 0x00000000029BBB70>
<function double.<locals>.<lambda> at 0x00000000029BBBF8>
<function double.<locals>.<lambda> at 0x00000000029BBD90>
<function double.<locals>.<lambda> at 0x00000000029BBE18>
16
对这个结果,我有些不太清楚的地方:
-
print(double(inc)(0))时只调用了一次double(f),这个没问题。但为什么print((double(double))(inc)(0))调用了3次double(f)而不是2次?多的一次<function double.<locals="">.<lambda> at 0x00000000029BBC80>做了什么?
-
为什么print((double(double(double)))(inc)(0)输出的是16而不是8?按我的分析这个是在(double(double))(inc)的基础上又double了一次,相当于*4啊。
-
调试python程序时有没有类似C中的debug工具可以用来打断点?
谢谢!
Answers
分清楚double了什么就能明白了。
下面用 . 表示函数组合,即 f (g (x)) = (f . g) x, 函数组合组合是满足结合律的,即 f . g . h = f . (g . h)。
double f = f . f
double (double f)
= double (f . f)
= (f . f . f . f)
(double double) f
= (double . double) f --> 多的一次double展开,下面和double (double f)相同的。
= double (double f)
= double (f . f)
= f . f . f . f
(double (double double)) f
= ((double double) . (double double)) f
= (double . double . double . double) f
= double . double . double (double f)
= double . double . doubel . (f . f)
= ...
= f . f . f . f . f . f . f . f . f . f . f . f . f . f . f . f
这就像是 2 * 2 * ... * 2 和 2 ^ 2 ^ ... ^ 2的差别。
如果你用三次的就很明显了: