# 数学家函数编程¶

## 编程风格¶

Python支持多种编程风格。您可以通过编写一个作为指令列表的程序样式来编程。假设您要对整数实现加法和乘法。这样做的程序程序如下：

sage: def add_ZZ(a, b):
....:     return a + b
...
sage: def mult_ZZ(a, b):
....:     return a * b
...
5
sage: mult_ZZ(2, 3)
6


Python模块 operator 将几个常用的算术和比较运算符定义为命名函数。加法在内置函数中定义 operator.add 乘法的定义见 operator.mul . 上面的例子可以按如下方式进行：

sage: from operator import add
sage: from operator import mul
5
sage: mul(2, 3)
6


sage: class MyInteger:
....:     def __init__(self):
....:         self.cardinality = "infinite"
....:         return a + b
....:     def mult(self, a, b):
....:         return a * b
...
sage: myZZ = MyInteger()
sage: myZZ.cardinality
'infinite'
5
sage: myZZ.mult(2, 3)
6


## 基于map的函数式程序设计¶

map(func, seq1, seq2, ...)


[func(seq1[0], seq2[0], ...), func(seq1[1], seq2[1], ...), ...]


sage: A = [1, 2, 3, 4]
sage: B = [2, 3, 5, 7]
sage: [A[i] + B[i] for i in range(len(A))]
[3, 5, 8, 11]


sage: from operator import add
sage: A = [1, 2, 3, 4]
sage: B = [2, 3, 5, 7]
[3, 5, 8, 11]


## 使用lambda定义小函数¶

sage: def add_ZZ(a, b): return a + b
...


sage: add_ZZ = lambda a, b: a + b
sage: mult_ZZ = lambda a, b: a * b
5
sage: mult_ZZ(2, 3)
6


sage: def crt(A, M):
....:     Mprod = prod(M)
....:     Mdiv = list(map(lambda x: Integer(Mprod / x), M))
....:     X = list(map(inverse_mod, Mdiv, M))
....:     x = sum([A[i]*X[i]*Mdiv[i] for i in range(len(A))])
....:     return mod(x, Mprod).lift()
...
sage: A = [2, 3, 1]
sage: M = [3, 4, 5]
sage: x = crt(A, M); x
11
sage: mod(x, 3)
2
sage: mod(x, 4)
3
sage: mod(x, 5)
1


sage: MS = MatrixSpace(ZZ, nrows=5, ncols=3)
sage: MS.random_element()  # random
<BLANKLINE>
[ 6  1  0]
[-1  5  0]
[-1  0  0]
[-5  0  1]
[ 1 -1 -3]


sage: random_matrix(ZZ, nrows=5, ncols=3)  # random
<BLANKLINE>
[  2 -50   0]
[ -1   0  -6]
[ -4  -1  -1]
[  1   1   3]
[  2  -1  -1]


sage: rows = [randint(1, 10) for i in range(10)]
sage: cols = [randint(1, 10) for i in range(10)]
sage: rings = [ZZ]*10
sage: M = list(map(random_matrix, rings, rows, cols))
sage: M[0]  # random
<BLANKLINE>
[ -1  -3  -1 -37   1  -1  -4   5]
[  2   1   1   5   2   1  -2   1]
[ -1   0  -4   0  -2   1  -2   1]


sage: rand_row = lambda n: [randint(1, 10) for i in range(n)]
sage: rand_mat = lambda nrows, ncols: [rand_row(ncols) for i in range(nrows)]
sage: matrix(rand_mat(5, 3))  # random
<BLANKLINE>
[ 2  9 10]
[ 8  8  9]
[ 6  7  6]
[ 9  2 10]
[ 2  6  2]
sage: rows = [randint(1, 10) for i in range(10)]
sage: cols = [randint(1, 10) for i in range(10)]
sage: M = list(map(rand_mat, rows, cols))
sage: M = list(map(matrix, M))
sage: M[0]  # random
<BLANKLINE>
[ 9  1  5  2 10 10  1]
[ 3  4  3  7  4  3  7]
[ 4  8  7  6  4  2 10]
[ 1  6  3  3  6  2  1]
[ 5  5  2  6  4  3  4]
[ 6  6  2  9  4  5  1]
[10  2  5  5  7 10  4]
[ 2  7  3  5 10  8  1]
[ 1  5  1  7  8  8  6]


## 将序列还原为值¶

sage: from functools import reduce # py3
sage: L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
55
sage: sum(L)
55


sage: from functools import reduce # py3
sage: from operator import mul
sage: U = [1, 2, 3]
sage: V = [2, 3, 5]
23
sage: sum(map(mul, U, V))
23


sage: u = vector([1, 2, 3])
sage: v = vector([2, 3, 5])
sage: u.dot_product(v)
23


sage: from functools import reduce # py3
sage: def crt(A, M):
....:     Mprod = prod(M)
....:     Mdiv = list(map(lambda x: Integer(Mprod / x), M))
....:     X = map(inverse_mod, Mdiv, M)
....:     mul3 = lambda a, b, c: a * b * c
....:     x = reduce(add, map(mul3, A, X, Mdiv))
....:     return mod(x, Mprod).lift()
...
sage: A = [2, 3, 1]
sage: M = [3, 4, 5]
sage: x = crt(A, M); x
11


## 用过滤器过滤¶

Python内置函数 filter 接受一个参数和一个序列的函数。然后它返回给定序列中所有这些项的列表，这样新列表中的任何项都会导致给定函数返回 True . 从某种意义上说，您过滤掉了满足给定函数中定义的某些条件的所有项。例如，您可以使用 filter 过滤掉1到50之间的所有素数。:

sage: list(filter(is_prime, [1..50]))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]


sage: [k for k in range(1, 21) if gcd(k, 20) == 1]
[1, 3, 7, 9, 11, 13, 17, 19]


sage: is_coprime = lambda k: gcd(k, 20) == 1
sage: list(filter(is_coprime, range(1, 21)))
[1, 3, 7, 9, 11, 13, 17, 19]


sage: def primroots(p):
....:     g = primitive_root(p)
....:     znorder = p - 1
....:     is_coprime = lambda x: gcd(x, znorder) == 1
....:     good_odd_integers = filter(is_coprime, [1..p-1, step=2])
....:     all_primroots = [power_mod(g, k, p) for k in good_odd_integers]
....:     all_primroots.sort()
....:     return all_primroots
...
sage: primroots(3)
[2]
sage: primroots(5)
[2, 3]
sage: primroots(7)
[3, 5]
sage: primroots(11)
[2, 6, 7, 8]
sage: primroots(13)
[2, 6, 7, 11]
sage: primroots(17)
[3, 5, 6, 7, 10, 11, 12, 14]
sage: primroots(23)
[5, 7, 10, 11, 14, 15, 17, 19, 20, 21]
sage: primroots(29)
[2, 3, 8, 10, 11, 14, 15, 18, 19, 21, 26, 27]
sage: primroots(31)
[3, 11, 12, 13, 17, 21, 22, 24]


## 更多资源¶

Python中函数式编程的另一个有用资源是 Functional Programming HOWTO 作者：A.M.Kuchling。史蒂芬·洛特的书 Building Skills in Python 有一章 Functional Programming using Collections . 另见本章 Functional Programming 从马克·皮尔格林的书中 Dive Into Python .