内置高阶函数¶
在变量那一节我们讲了变量是指向数据(对象)的标签,也就意味着变量可以指向任意类型,变量指向函数肯定是可以的。既然函数也可以看成变量,那么把函数作为参数传递给函数会怎么样呢?这就是本节的内容,接收函数作为参数的函数称为高阶函数。
map函数¶
map顾名思义就是映射的意思,接收两个参数,第一个参数为函数,第二个参数为可迭代对象。map会把这个函数并行的作用在可迭代对象的每一个元素上。先来看个例子。
>>> l = [1, 2, 3, 4]
>>> q = map(lambda x: x**2, l) # 返回map对象
>>> list(q) # 转为list
[1, 4, 9, 16]
上面的函数是对输入参数进行平方操作,map会将这个函数映射到每一个参数上。如果输入参数是多个怎么办,迭代对象的个数与函数的输入参数保持一致。
>>> q = map(lambda x, y: x+y, 'ABC', 'XYZ')
>>> list(q)
['AX', 'BY', 'CZ']
reduce函数¶
reduce函数以前是内置函数,如果你的Python版本没有reduce
函数,可以尝试从functools
模块导入。
from functools import reduce
reduce函数也是一种高阶函数,按照某种操作对可迭代对象进行归纳运算。reduce可以实现很多操作,我们简单看几个例子,1+2+...+100, n!, 2^{3^4}。详细的信息参考help文档。
>>> reduce(lambda x, y: x+y, range(1, 101)) # 计算从1到100的和
5050
>>> reduce(lambda x, y: x*y, range(1,6)) # 计算5!=120
120
>>> reduce(lambda x, y: y ** x, [4,3,2]) # 2^3^4
2417851639229258349412352
filter函数¶
filter
是一个过滤器函数,接受函数和迭代对象作为参数,将函数映射到每个迭代对象的元素上,如果函数返回结果为True
则结果保留,如果为False
将会被过滤掉。看一个简单的例子,输出0-9的10个数字中的偶数。
>>> res = filter(lambda x: x % 2 == 0, range(10))
>>> list(res)
[0, 2, 4, 6, 8]
lambda
函数只是一种匿名函数,无法实现复杂功能,可以自定义复杂的函数,返回结果为布尔值。除此之外filter
可以接受函数为None
,这就意味只返回迭代对象中布尔运算为True的元素。
>>> list(filter(None, [None, 1, 0, False, [], '', 100, "abc"]))
[1, 100, 'abc']
>>> bool(None)
False
>>> bool('')
False
没有返回的元素,其布尔运算的结果都是False
。
接下来再补充一个函数zip
,将多个迭代对象做组合,输入参数为两个或两个以上的迭代对象,每个迭代对象的元素个数如果不一致,以最短的迭代对象的长度作为返回长度。
>>> list(zip([1,2,3], 'abcd'))
[(1, 'a'), (2, 'b'), (3, 'c')]
如果需要组合多个对象,直接作为参数传给zip
函数即可。除了组合参数,还可以把组合的结果拆开
>>> data = [(1, 'a'), (2, 'b'), (3, 'c')]
>>> d1, d2 = zip(*data)
>>> d1
(1, 2, 3)
>>> d2
('a', 'b', 'c')
总结¶
本节内容一共讲了4个函数,其中3个是高阶函数:
- map 映射函数,将函数映射到迭代对象的每一个元素上,返回映射函数作用的结果,返回map对象。
- reduce 归纳函数,有累积循环的效果。将上一次操作结果作为第一个参数继续传入函数中。
- filter 过滤器函数,将函数依次作用在迭代对象上,返回True的元素结果。
- zip 数据组合函数,将多个迭代对象进行组合。