Python中的map, filter,reduce
写在前面:
剖析列举的几个函数,从知识广度上讲,显然不大够,未来将不定期更新、补充,如有建议和问题,烦请告知我,我会虚心接受所有批评和建议,使得本文内容不断完善和丰富。欢迎讨论。
尝试使用Python中的一些技巧(比如说列表推导式、生成器推导式、lambda、高级函数)会让代码变得简洁,更加Pythonic。
map
map(function, iterable, …)
在使用map()
时,请注意几点:
- 先传入由你指定的函数,再传入可迭代(对象)
>>> map(function, iterable)
| |
| |_ _ 传入的可迭代元素(iterable),比如[1,2,3,4,5]
|_ _ 指定函数,如lambda x: x*x,来计算迭代参数中的每个元素的平方
>>> a = map(lambda x: x*x, [1,2,3,4,5])
>>> type(a)
<class 'map'>
>>> list(a)
[1, 4, 9, 16, 25]
- 在传入的多种可迭代参数中,
map()
会从各个可迭代参数中平行的传入元素进函数(function),当最短的可迭代参数的元素应用完项目之后,map()
将停止,并返回。
>>> b = map(lambda x, y: x*y, [x for x in range(1,6)], [3 for x in range(5)])
>>> list(b)
[3, 6, 9, 12, 15]
>>> # 下面的示例中第二个可迭代参数更短一些
>>> c = map(lambda x, y: x*y, [x for x in range(1,6)], [3 for x in range(3)])
>>> list(c)
[3, 6, 9]
fileter
filter(function, iterable)
filter
(过滤,可以这么理解),会生成一个由可迭代参数(它可以是序列、列表、字符串及其他容器)的元素传入函数function
使得其返回为True
的迭代器。也就是说,filter(function, iterable
,相当于写法(item for item in items if function(item))
,下面的简单实例过滤,得到一个1到12的中所有为可整除3的整数。
>>> f = filter(lambda x: x%3==0, [i for i in range(1, 13)])
>>> next(f)
3
>>> next(f)
6
>>> next(f)
9
>>> next(f)
12
>>> next(f)
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
# 以下例子可以窥见filter因何而不常用
# 假如,我需要1到300以内既要能被7整除又要能被13整除的所有整数
# 使用filter
>>> [i for i in filter(lambda x: x%7==0 and x%13==0, range(1, 301))]
[91, 182, 273]
# 然而,不必要麻烦
>>> [i for i in range(1, 301) if i%7==0 and i%13==0]
[91, 182, 273]
- 当指定的
function
为None时,会有指定的函数代替,filter
返回可迭代参数中不为None的所有元素。
>>> [i for i in filter(None, range(1, 12))]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> [i for i in filter(None, [True for i in range(5)])]
[True, True, True, True, True]
>>> [i for i in filter(None, [False for i in range(5)])]
[]
reduce
reduce(function, iterable[, initializer])
使用reduce,需要引入
functools
模块。
reduce
将会从列表(sequence)中的各项中累积(函数的结果不断加和)地加和调用了二元参数函数(function)的结果。也就是说,传入一个二元参数函数与可迭代列表,最终将会返回一个值,而这个值是每一个可迭代列表的子项,传入函数得出的结果之和。
>>> from functools import *
>>> reduce(lambda x, y: x+y, [1,2,3,4,5])
15 | |
| |_ _ 右边参数,y,将会从列表(sequence)中得到更新
|_ _ 左边参数,x,是会进行累积的值,函数返回值
>>> # 实现一个阶乘 factorial()
>>> def factorial(n : int) -> int:
if n == 0 or n == 1:
return 1
if n < 0:
return -1
return reduce(lambda x, y: x*y, range(1, n+1))
>>> factorial(5)
120
- 要记住,
reduce
可以传入另外一个可选的参数initializer
,可以按照以下代码,理解为:
reduce(function, iterable, initializer)
==reduce(function, iterable)+initializer
>>> # ((((1+2)+3)+4)+5) = 15
>>> reduce(lambda x, y: x+y, [x for x in range(1, 6)])
15
>>> # ((((1+2)+3)+4)+5) + 10 = 25
>>> reduce(lambda x, y: x+y, [x for x in range(1, 6)], 10)
25
待更标记…