Chapter1: 使用函数构建抽象
高阶函数
作为一般方法的函数
sum_naturals()
1
2
3
4
5
6
7def sum_naturals(n):
total, k = 0, 1
while k <= n:
total, k = total + k, k + 1
return total
100) sum_naturals(
5050sum_cube()
1
2
3
4
5
6
7def sum_cubes(n):
total, k = 0, 1
while k <= n:
total, k = total + pow(k, 3), k + 1
return total
100) sum_cubes(
25502500sum_pi()
1 | def pi_sum(n): |
这三个函数在背后都具有相同模式。它们大部分相同,只是名字、用于计算被加项的k的函数,以及提供k的下一个值的函数不同。我们可以通过向相同的模板中填充槽位来生成每个函数:
1 | def <name>(n): |
对于以上三个函数我们可以抽象成以下函数:
1 | def summation(n, term, next): |
要注意summation接受上界n,以及函数term和next作为参数。我们可以像任何函数那样使用summation,它简洁地表达了求和。
sum_cube()
1
2
3
4
5
6
7
8def cube(k):
return pow(k, 3)
def successor(k):
return k + 1
def sum_cubes(n):
return summation(n, cube, successor)
3) sum_cubes(
36sum_pi()
1
2
3
4
5
6
7
8
9
10
11def pi_term(k):
return 8 / (k * (k + 2))
def pi_next(k):
return k+4
def sum_pi(n):
return summation(n, pi, next)
1e6) pi_sum(
3.1415906535898936计算黄金分割比(gold ratio)
1
2
3
4
5
6def golden_update(guess):
return 1/guess + 1
def golden_test(guess):
return near(guess, square, successor)
iter_improve(golden_update, golden_test)
1.6180371352785146
$Lambda$ 表达式
Python 中,我们可以使用 Lambda 表达式凭空创建函数,它会求值为匿名函数。Lambda 表达式是函数体具有单个返回表达式的函数,不允许出现赋值和控制语句。
1
2 lambda x : f(g(x))
"A function that takes x and returns f(g(x))"
1 | 1 def compose1(f, g): |
抽象和一等函数
作为程序员,我们应该留意识别程序中低级抽象的机会,在它们之上构建,并泛化它们来创建更加强大的抽象。这并不是说,一个人应该总是尽可能以最抽象的方式来编程;专家级程序员知道如何选择合适于他们任务的抽象级别。但是能够基于这些抽象来思考,以便我们在新的上下文中能使用它们十分重要。高阶函数的重要性是,它允许我们更加明显地将这些抽象表达为编程语言中的元素,使它们能够处理其它的计算元素。
通常,编程语言会限制操作计算元素的途径。带有最少限制的元素被称为具有一等地位。一些一等元素的“权利和特权”是:
- 它们可以绑定到名称。
- 它们可以作为参数向函数传递。
- 它们可以作为函数的返回值返回。
- 它们可以包含在数据结构中。
- Python 总是给予函数一等地位,所产生的表现力的收益是巨大的。另一方面,控制结构不能做到:你不能像使用sum那样将if传给一个函数。