接收函数为参数或者把函数作为结果返回的函数是高阶函数。
Map,Filter和Reduce是函数式编程的范例。 它们使程序员可以编写更简单,更短的代码,而不必担心诸如循环和分支之类的复杂问题。
这三个函数可以将一个函数应用于多个可迭代对象。 map()
和filter()
是Python内置的(在__builtins__
模块中),不需要导入。 但是reduce()
在functools
模块中,因此需要导入。
\quad
filter()
filter()
函数用于过滤列表中的元素,并且返回一个由所有符合要求的元素所构成的列表。它接收一个函数和一个序列,把函数作用在序列的每个元素上,然后根据返回值是True
还是False
决定保留还是丢弃该元素。
它具有以下语法:
filter(func, iterable)
关于filter()
,需要注意以下几点:
func
参数才能返回布尔类型。 如果不是,filter()
仅返回传递给它的可迭代对象。 另外,由于仅需要一个可迭代的函数,因此隐含的是func
必须仅接受一个参数。filter()
通过func
传递可迭代对象中的每个元素,并仅返回评估为True
的那些元素。filter()
返回的是一个迭代器。例子1:保留奇数列表
>>> mylist = list(range(10))
>>> list(filter(lambda x: x % 2 == 1, mylist))
[1, 3, 5, 7, 9]
例子2:保留小于0的数
>>> number_list = range(-5, 5)
>>> less_than_zero = filter(lambda x: x < 0, number_list)
>>> print(list(less_than_zero))
[-5, -4, -3, -2, -1]
例子3:回文(palindrome)检测器。 从候选回文的元组(可迭代对象)中过滤掉属于回文的单词。
“回文”是单词、词组或序列,其向后读取与向前读取相同。
>>> dromes = ("demigod", "rewire", "madam", "freer", "anutforajaroftuna", "kiosk")
>>> palindromes = list(filter(lambda w: w == w[::-1], dromes))
>>> palindromes
['madam', 'anutforajaroftuna']
\quad
map()
map()
会将⼀个函数映射到⼀个输入列表的所有元素上。这是它的规范:
map(function_to_apply, list_of_inputs)
map()
函数传入一个函数和一个序列,并把函数作用到序列的每个元素上,返回一个可迭代对象。
大多数时候,我们要把列表中所有元素⼀个个的传递给⼀个函数,并收集输出。比如
items = [1, 2, 3, 4, 5]
squared = []
for i in items:
squared.append(i ** 2)
map()
函数可以让用⼀种简单⽽漂亮的⽅式来实现。
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, items))
还有更多的例子:
>>> list(map(lambda x: x % 2, mylist))
[1, 0, 1, 0, 1, 0, 1, 0, 1]
>>> list(map(lambda x: x * 2, mylist))
[2, 4, 6, 8, 10, 12, 14, 16, 18]
大多数时候,我们使用匿名函数来配合map()
。 此外map()
不仅可以于⼀列表的输⼊, 甚⾄可以用于⼀个列表的函数。比如:
def add(x):
return x + x
def multiply(x):
return x * x
>>> funcs = [add, multiply]
>>> for i in range(5):
... value = map(lambda x: x(i), funcs)
... print(list(value)) # map()返回一个迭代器!
[0, 0]
[2, 1]
[4, 4]
[6, 9]
[8, 16]
filter()
函数类似于一个 for
循环,但它是一个内置函数,速度更快。
事实上,在 Python 3 中,map()
和 filter()
虽然还是内置函数,但是由于引入了列表推导和生成器表达式,它们变得没那么重要了。列表推导或生成器表达式具有 map
和 filter
两个函数的功能,而且更易于阅读。
在 Python 3 中,map()
和 filter()
返回生成器,因此现在它们的直接替代品是生成器表达式。
\quad
reduce()
当需要对一个列表进行一些计算并返回结果时,reduce()
是个非常有用的函数。
reduce()
函数用于递归计算。reduce()
将两个参数的函数从初始参数开始累积地应用于可迭代对象的元素。 reduce()
函数同样需要传入一个函数和一个序列。它具有以下语法:
reduce(func, iterable[, initial])
其中
func
是对iterable
中的每个元素累积应用的函数,而initial
是在计算中置于iterable
元素之前的可选值,并且在iterable
为空时用作默认值。func
需要两个参数,第一个是iterable
中的第一个元素(如果未提供initial
)。 第二个是iterable
中的第二个元素。 如果提供了initial
,则它将成为func
的第一个参数,而iterable
中的第一个元素将成为第二个元素。reduce()
将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce()
中的 function
函数 (有两个参数)先对集合中的第1和2个元素进行操作,得到的结果再与第三个数据用 function
函数运算,最后得到一个结果。
例如:
from functools import reduce
reduce(lambda x, y: x + y, range(101))
reduce()
的应用:
reduce(lambda x, y: x * y, range(1, 10))
计算列表中所有元素的最大值:
reduce(lambda x, y: x if x > y else y, [1, 2, 3, 4])
现在有一个列表:[3, 5, 8, 1]
对应的是3581的每一个数字,要从这个列表计算出原来的数,可以这样做:
reduce(lambda x, y: x * 10 + y, [3, 5, 8, 1])
在 Python 2 中,reduce()
是内置函数,但是在 Python 3 中放到 functools
模块里了。这个函数最常用于求和,但现在最好使用内置的sum
函数。
\quad
可以看出,上面的三个函数与匿名函数相结合使用,可以写出强大简洁的代码。
\quad