跳转至

内置高阶函数

在变量那一节我们讲了变量是指向数据(对象)的标签,也就意味着变量可以指向任意类型,变量指向函数肯定是可以的。既然函数也可以看成变量,那么把函数作为参数传递给函数会怎么样呢?这就是本节的内容,接收函数作为参数的函数称为高阶函数。

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 数据组合函数,将多个迭代对象进行组合。

评论