《Python进阶系列》三:Python中的 Map,Filter 和 Reduce用法

Python中的 Map,Filter 和 Reduce

接收函数为参数或者把函数作为结果返回的函数是高阶函数

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() 虽然还是内置函数,但是由于引入了列表推导和生成器表达式,它们变得没那么重要了。列表推导或生成器表达式具有 mapfilter 两个函数的功能,而且更易于阅读。

在 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

参考

  • https://eastlakeside.gitbook.io/interpy-zh/map_n_filter
  • https://blog.csdn.net/bai666ai/article/details/123973488

你可能感兴趣的:(Python进阶,python,开发语言)