函数式编程
函数式编程源自于数学理论,它似乎也更适用于数学计算相关的场景,因此本文以一个简单的数据处理问题为例,逐步介绍 Python 函数式编程从入门到走火入魔的过程。
问题:计算 N 位同学在某份试卷的 M 道选择题上的得分(每道题目的分值不同)。
首先来生成一组用于计算的伪造数据:
1 |
|
通过创建嵌套两个 for 循环来遍历所有题目答案的判断和评分,这完全是为计算机服务的思路,虽然说 Python 中的 for 循环已经比 C 语言更进了一步,通常不需要额外的状态变量来记录当前循环的次数,但有时候也不得不使用状态变量,如上例中第二个循环中比较两个列表的元素。函数式编程的一大特点就是尽量抛弃这种明显循环遍历的做法,而是把注意集中在解决问题本身,一如在现实中我们批改试卷时,只需要将两组答案并列进行比较即可:
from data import students, QUIZE
student = students[0]
# 将学生答案与正确答案合并到一起
# 然后过滤出答案一致的题目
filtered = filter(lambda x: x[0] == x[1][0], zip(student.ans, QUIZE))
print(list(filtered))
# [('A', ('A', 3)), ('D', ('D', 1)), ...]
正确题目的分数进行累加:
from functools import reduce
reduced = reduce(lambda x, y: x + y[1][1], filtered, 0)
print(reduced)
接下来进行推广:
def cal(quize):
def inner(student):
filtered = filter(lambda x: x[0] == x[1][0], zip(student.ans, quize))
reduced = reduce(lambda x, y: x + y[1][1], filtered, 0)
print(student.id, '\t', reduced)
return inner
map(cal(QUIZE), students)