Python 中的高阶函数

python 对函数式编程(Functional Programming)的重要支持方式就是允许把函数本身作为参数传入另一个函数,还允许返回一个函数。由此可以引申出高阶函数(Higher-order function)

一、高阶函数

接收其他函数作为参数的函数称之为高阶函数。

一个简单的例子:

1
2
def add(x,y,f = abs):     # abs 作为BIF 不带括号时直接将函数本身赋值给 
return f(x) + f(y)

此时 调用 add(-5,6),会返回11.因为 add 函数接受了函数 f 作为参数。

二、map/reduce

map/reduce 是最为常用的 Python 内建的高阶函数之一。

1. map

map() 函数接收两个参数,一个是函数,另一个是 Iterable ,主要功能就是将传入的函数以此作用在 Iterable 中的每个元素上,并把结果作为新的 Iterator 返回。

e.g:

1
2
3
4
5
6
>>> def f(x):      #将函数 f 作用在 list[1, 2, 3, 4, 5, 6, 7, 8, 9] 上 返回
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r) #Iterator 是惰性序列,需要用list()将其转换为list
[1, 4, 9, 16, 25, 36, 49, 64, 81]

可以看出的是,map() 将运算规则抽象出来,形成清晰的映射关系。

2.reduce

reduce() 把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f,[x1,x2,x3,x4]) = f(f(f(x1,x2),x3),x4)

例如将一个字符串转换为整数的函数:

1
2
3
4
5
6
7
from functools import reduce

def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s)) #lambda 匿名函数

首先使用map函数将s字符串序列转换为数字序列返回,然后通过lambda表达式的运算转换为十进制整数。

三、常用内建高阶函数

1.filter()

e.g. 打印 1000以内的回数(用 filter 过滤掉非回数)
filter() 函数也接收一个函数和一个序列,接受的函数应该返回 True和 False 。将函数依次作用于序列的各个元素上,当返回 False 时将该元素丢弃。

1
2
3
4
5
6
7
8
def is_palindrome(n):
if str(n) != str(n)[::-1]:
return False
else:
return True

output = filter(is_palindrome, range(1, 1000))
print(list(output))

2. sorted()

sorted() 函数就是排序算法,可以直接对 list 进行排序。高阶函数的用法主要是接收 key 函数,key() 函数将作用于 list 中的每一个元素上,并根据key()的返回值形成的list重新排序。
reverse 参数用来改变正逆序,reverse = True 时,按逆序排列。

与之类似的是 list.sort() 方法,原地排序。

假设用一组 tuple 表示学生名字和成绩:

L = [(‘Bob’, 75), (‘Adam’, 92), (‘Bart’, 66), (‘Lisa’, 88)]

用 sorted() 对 L 分别按按名字正序,成绩c从高到低排列:

1
2
3
4
5
6
7
8
def by_name(t):
return t[0]

def by_grade(t):
return t[1]

L2 = sorted(L,key = by_name) # key 多传入lambda表达式
L3 = sorted(L.key = by_grade)