python - SICP 练习 1.41

标签 python algorithm debugging

Exercise 1.41. Define a procedure double that takes a procedure of one argument as argument and returns a procedure that applies the original procedure twice. For example, if inc is a procedure that adds 1 to its argument, then (double inc) should be a procedure that adds 2. What value is returned by (((double (double double)) inc) 5)

我用 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

我的问题是:

  1. 为什么输出 print((double(double(double)))(inc)(0)是 16 而不是 8?

  2. 为什么double的功能运行时调用了 3 次而不是 2 次 (double(double))(inc)(0)

  3. 有没有调试工具可以在 python 中设置断点,比如 C 中的“gdb”,以便我调试这个程序?

谢谢!

最佳答案

让我们分析一下您的代码:

print( double(inc)(0) )

所以这将调用带有参数 inc 的函数 double。因此,正如预期的那样,它将返回一个函数,该函数将对一个参数应用函数 inc 两次。所以你会得到 2 作为输出。你做对了。

现在,有趣的地方来了:

print( (double(double))(inc)(0) )

请注意,您已使用参数 double 调用函数 double,然后使用参数 inc 调用结果函数。所以这就是发生的事情:

  1. 调用 double(double) # 也就是说,double 带有参数 double(第一次调用 double)
  2. 你得到一个函数,它将对参数调用 double 两次
  3. 您在 inc 上使用该函数。
  4. 所以你得到一个函数,它将两次应用 doubleinc (这里有两次调用 double )<

你得到的是一个递增 4 的函数。实际上这不是 2*2,而是 2^2,2^2 = 2*2 = 4 只是巧合(或不巧合),所以你仍然得到 4 的答案。

第三次打印:

print((double(double(double)))(inc)(0)

实际上,您对 double(double) 的结果调用了 double,这将对自身应用函数 double(double) 两次。如此有效地调用 double(double)(double(double(inc)))。因此,您应用函数 inc 2*2*(2*2) = 16 次。

为了更好地理解这一点,请注意:

print( double(double(double(inc)))(0) )

将打印 8。

关于python - SICP 练习 1.41,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19107431/

相关文章:

c - 如何快速对许多正则表达式键进行字符串匹配?

android - 使用 Android USB 设备时可以使用 e.PrintStackTrace() 或断点吗?

Android Studio 在 Logcat 中缺少异常堆栈跟踪

python - 有没有办法让 simplejson 不那么严格?

python - 树hackerrank解决错误的故事

algorithm - 逐像素贝塞尔曲线

java - 修改矩阵并将列和行设置为零的算法

ios - 是否可以跟踪 UIView 框架的更改?

python - 使用 numba 提供显式类型时,njit 编译期间出现输入错误

python - 清除列表以删除半重复值