3.python中map,filter,reduce以及内部实现原理剖析

  1. 云栖社区>
  2. 博客>
  3. 正文

3.python中map,filter,reduce以及内部实现原理剖析

技术小胖子 2017-11-14 15:29:00 浏览573
展开阅读全文

一.map函数,对任何可迭代序列中的每一个元素应用对应的函数。(不管处理的是什么类型的序列,最后返回的都是列表。)

作用已经在标题中介绍过了,那么先来说说map函数的用法吧。

map(处理逻辑可以是函数也可以是lambda表达式,可迭代的序列)

现在有一个列表。

l1 = [1,2,3,4,5]

现在需要给这个列表里的每一个元素都+1。(当然,使用for循环可以做到对序列中的每个元素进行处理,但使用map函数会更加方便。)

首先,定义一个逻辑函数,要如何对序列中的每一个元素进行处理。

def plus(x):

    return x + 1

#每个元素都+1

print map(plus,l1)

#将map函数应用到l1的每一个元素中。

输出的结果为。

>>>[2, 3, 4, 5, 6]


当然,传入map函数中的逻辑函数还可以使用lambda表达式来表示,还拿刚才的例子演示。

l1 = [1,2,3,4,5]

print map(lambda x:x+1,l1)

>>>[2, 3, 4, 5, 6]


那么map函数是怎么做到的?内部功能是如何实现的?下面就来对map函数的内部进行剖析。

下面这个函数就可以实现和python内置的map函数一模一样的功能。

def map_func(func,seq):

    map_list = []

    for i in seq:

        map_list.append(func(i))

    return map_list


注意!上面说的map函数的使用方法是针对python2.7版本的,针对python3以上的版本不适用,因为从python3开始,map函数不再返回列表,返回的则是一个迭代器,如果想变成列表的话,还需要使用list() 函数做一个转换。



二.filter函数,对序列中的元素进行判断筛选。(返回的结果依旧是个列表。)

fileter函数在拿到一个序列的时候,会开始循环迭代这个序列中的每一个元素,对每一个元素都进行一次if判断,结果为True的加入到列表中,为False的,直接丢掉。

下面是filter函数的简单用法。

一个列表,将这个列表中小于5的元素,全部都列出来。(当然...这么简单的需求也可以使用for循环实现)

filter函数用法和map函数一样都是 filter(函数,可迭代序列)

l1 = [1,2,3,4,5,6,7,8,9,10]


def greater_than(x):

    if x < 5:

        return True

    else:

        return False


print filter(greater_than,l1)

>>>[1, 2, 3, 4]


filter函数依旧可以使用lambda表达式来代替逻辑函数。

print filter(lambda x:x<5,l1)


下面来剖析一下filter函数的工作原理,自己手动写一个和filter功能一模一样的函数:

def filter_func(func,seq):

    filter_list = []

    for s in seq:

        if func(s):

            filter_list.append(s)

    return filter_list


注意啦!这里面的filter函数和map函数一样,用法都是针对python2.7的,在python3中对这个函数做了一些改动,返回的不再是个列表,而是个迭代器。


三.reduce函数,将序列中所有的元素进行合并运算。

现在有个列表,现在需要每个元素要逐个相乘。


l1 = [1,2,3,4,5,6,7,8,9,10]

#reduce函数规定了,一定要传递一个支持一个二元操作的函数

#下面就是定义好的逻辑函数

def bin_func(x,y):

    return x * y


print reduce(plus,l1)

>>> 3628800

下图是reduce函数的工作原理:

wKioL1jNAN2A82opAAC63NnUCNs013.png


接下来,解剖下reduce函数的实现代码。

def reduce_func(func,seq,init_num=None):

    if init_num != None:

        ret = init_num

    else:

        ret = seq.pop(0)

    for i in seq:

        ret=func(ret,i)    #如果这条逻辑不好理解的话,可以仔细想想1*2*3*4 = ((1*2)*3)*4 

    return ret


print reduce_func(bin_func,l1)


>>>3628800


reduce函数使用lambda表达式。

print reduce_func(lambda x,y:x*y,l1)


注意!在python3当中,这个reduce函数被放到了functools这个模块中了,需要倒入functools才可以使用这个函数。


最后总结一下:

map函数用于处理序列中每一个元素。

filter函数用于过滤序列中每一个元素。

reduce函数用于做序列的合并操作。

reduce即为化简,它是这样一个过程:每次迭代,将上一次的迭代结果(第一次时为init的元素,如没有init则为seq的第一个元素)与下一个元素一同执行一个二元的func函数。在reduce函数中,init是可选的,如果使用,则作为第一次迭代的第一个元素使用。






      本文转自苏浩智 51CTO博客,原文链接:http://blog.51cto.com/suhaozhi/1907951,如需转载请自行联系原作者





网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注