[python] python 中map、reduce和filter 浅析

来源:互联网 发布:康奈尔大学商学院 知乎 编辑:程序博客网 时间:2024/06/05 12:07

0x00      map()

如果你想先了解下什么是map()和reduce(),可以参考MapReduce:Simplified Data Processing On Large Clusters这篇文章。

map() 和 reduce() 都是python 内置函数 

可以看到在python文档中对map() 、reduce()的描述:

https://docs.python.org/3.4/library/functions.html#map


map(functioniterable...)

Return an iterator that applies function to every item of iterable, yielding the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For cases where the function inputs are already arranged into argument tuples, see itertools.starmap().

可以看到,map()函数接受两个参数,function和iterable , function是函数对象,多数时候是自定义的函数,第二个参数iterable是一个可迭代对象,而map()函数的功能就是将函数function作用在可迭代对象iterable中的每一个元素上,并生成一个新的列表,也就是说,我们也可以对tuple等不可改变对象进行map()操作。现在举个map()的例子,假设我们有一个已经排好序的列表 [1,2,3,4,5,6,7], 现在我需要将他们每一个数都乘10再加1,那么用map()函数来实现就是这样:

>>> a = [1, 3, 4, 7, 9, 18]>>> b = map( lambda x: x*10+1, a)>>> b[11, 31, 41, 71, 91, 181]

0x01     reduce()


关于reduce描述在文档中也有描述,不过在python3.x中,reduce()函数被放置在functools模块中,所以使用前需要导入

from functools import reduce

首先来看看文档中关于reduce()函数的描述
functools.reduce(functioniterable[initializer])

Apply function of two arguments cumulatively to the items of sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the sequence. If the optional initializer is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty. If initializer is not given and sequence contains only one item, the first item is returned.

Roughly equivalent to:

def reduce(function, iterable, initializer=None):    it = iter(iterable)    if initializer is None:        value = next(it)    else:        value = initializer    for element in it:        value = function(value, element)    return value
原理上面说的很清楚来,reduce好像是在读书一样,每次读到的新东西都会和你所有学过的东西进行融合,比如:
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 就代表着 ((((1+2)+3)+4)+5)
reduce()函数接受三个参数其中最后一个参数为缺省参数,function为作用函数,该函数参数必须是两个。iterable是一个可迭代对象。initializer是默认元素,如果不传入initializer,会默认为None。要注意的是,在函数reduce()执行时,会先检查initializer添加到可迭代列表的最前面(当然如果是None就什么都没有发生),也就是说,在上面加法的例子中,如果传出的列表是 [ 1 , ] ,并且将缺省参数initializer指定为2,那么运算过程就是(2+1)。还有一种情况是列表中只有一个元素,缺省参数也是None,那么reduce函数返回的就是列表中那个唯一的元素,不做任何运算(因为没办法算)。当然如果列表为空,initializer参数也空,就会报错的。代码测试情况:
>>> list1 = [1, 2, 3, 4, 5 ]>>> list2 = [34, ]>>> list3 = []>>> def func(x, y):...     return x * y...>>> reduce(func, list1)120>>> reduce(func, list1, 6)720>>> reduce(func, list2)34>>> reduce(func, list2, 2)68>>> reduce(func, list3)Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: reduce() of empty sequence with no initial value
(ps:上面例子func为乘法函数。)

0x02     filter()



filter(functioniterable)

Construct an iterator from those elements of iterable for which function returns true. iterable may be either a sequence, a container which supports iteration, or an iterator. If function is None, the identity function is assumed, that is, all elements of iterable that are false are removed.

Note that filter(function, iterable) is equivalent to the generator expression (item for item in iterable if function(item)) 

if function is not None and (item for item in iterable if item) if function is None

See itertools.filterfalse() for the complementary function that returns elements of iterable for which function returns false.

filter翻译过来是过滤器,和map()类似,filter()函数也接受一个函数和一个可迭代序列,和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。


0 0