专栏首页Python小屋详解Python函数式编程之map、reduce、filter

详解Python函数式编程之map、reduce、filter

map()、reduce()、filter()是Python中很常用的几个函数,也是Python支持函数式编程的重要体现。不过,在Python 3.x中,reduce()不是内置函数,而是放到了标准库functools中,需要先导入再使用。

(1)map()。内置函数map()可以将一个函数依次映射到序列或迭代器对象的每个元素上,并返回一个可迭代的map对象作为结果,map对象中每个元素是原序列中元素经过该函数处理后的结果,该函数不对原序列或迭代器对象做任何修改。 >>> list(map(str, range(5))) #把列表中元素转换为字符串 ['0', '1', '2', '3', '4'] >>> def add5(v): #单参数函数 return v+5 >>> list(map(add5, range(10))) #把单参数函数映射到一个序列的所有元素 [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> def add(x, y): #可以接收2个参数的函数 return x+y >>> list(map(add, range(5), range(5,10))) #把双参数函数映射到两个序列上 [5, 7, 9, 11, 13] >>> list(map(lambda x, y: x+y, range(5), range(5,10))) [5, 7, 9, 11, 13] >>> def myMap(iterable, op, value): #自定义函数 if op not in '+-*/': #实现序列与数字的四则运算 return 'Error operator' func = lambda i:eval(repr(i)+op+repr(value)) return map(func, iterable) >>> list(myMap(range(5), '+', 5)) [5, 6, 7, 8, 9] >>> list(myMap(range(5), '-', 5)) [-5, -4, -3, -2, -1] >>> list(myMap(range(5), '*', 5)) [0, 5, 10, 15, 20] >>> import random >>> x = random.randint(1, 1e30) #生成指定范围内的随机整数 >>> x 839746558215897242220046223150 >>> list(map(int, str(x))) #提取大整数每位上的数字 [8, 3, 9, 7, 4, 6, 5, 5, 8, 2, 1, 5, 8, 9, 7, 2, 4, 2, 2, 2, 0, 0, 4, 6, 2, 2, 3, 1, 5, 0]

(2)reduce()。标准库functools中的函数reduce()可以将一个接收2个参数的函数以迭代累积的方式从左到右依次作用到一个序列或迭代器对象的所有元素上,并且允许指定一个初始值。例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])计算过程为((((1+2)+3)+4)+5),第一次计算时x为1而y为2,再次计算时x的值为(1+2)而y的值为3,再次计算时x的值为((1+2)+3)而y的值为4,以此类推,最终完成计算并返回((((1+2)+3)+4)+5)的值。 >>> from functools import reduce >>> seq = list(range(1, 10)) >>> reduce(add, seq) #add是上一段代码中定义的函数 45 >>> reduce(lambda x, y: x+y, seq) #使用lambda表达式实现相同功能 45

上面这两段代码的功能是一样的,执行过程如下图:

>>> import operator #标准库operator提供了大量运算 >>> operator.add(3,5) #可以像普通函数一样直接调用 8 >>> reduce(operator.add, seq) #使用add运算 45 >>> reduce(operator.add, seq, 5) #指定累加的初始值为5 50 >>> reduce(operator.mul, seq) #乘法运算 362880 >>> reduce(operator.mul, range(1, 6)) #5的阶乘 120 >>> reduce(operator.add, map(str, seq)) #转换成字符串再累加 '123456789' >>> ''.join(map(str, seq)) #使用join()方法实现字符串连接 '123456789' >>> reduce(operator.add, [[1, 2], [3], [4]], []) #这个操作占用空间较大,慎用 [1, 2, 3, 4]

与上面代码中最后演示的用法类似,作为一种技巧,reduce()函数还支持下面的用法(感谢浙江省浦江中学方春林老师提供本例用法): >>> from random import randint >>> lst = [randint(1, 10) for i in range(50)] #随机数列表 >>> def tjNum(dic, k): #统计元素出现次数 if k in dic: dic[k] += 1 else: dic[k] = 1 return dic

>>> from functools import reduce >>> reduce(tjNum, lst, {}) {1: 6, 2: 3, 3: 6, 4: 3, 5: 4, 6: 7, 7: 5, 8: 5, 9: 6, 10: 5}

(3)filter()。内置函数filter()将一个单参数函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的filter对象,如果指定函数为None,则返回序列中等价于True的元素。 >>> seq = ['foo', 'x41', '?!', '***'] >>> def func(x): return x.isalnum() #测试是否为字母或数字 >>> filter(func, seq) #返回filter对象 <filter object at 0x000000000305D898> >>> list(filter(func, seq)) #把filter对象转换为列表 ['foo', 'x41'] >>> [x for x in seq if x.isalnum()] #使用列表推导式实现相同功能 ['foo', 'x41'] >>> list(filter(lambda x: x.isalnum(), seq)) #使用lambda表达式实现相同功能 ['foo', 'x41'] >>> list(filter(None, [1, 2, 3, 0, 0, 4, 0, 5])) #指定函数为None [1, 2, 3, 4, 5]

本文分享自微信公众号 - Python小屋(Python_xiaowu),作者:董付国

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-12-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python快速计算Fibonacci数列中第n项的方法

    from time import time from functools import lru_cache def fibo1(n): '''递归法''' ...

    Python小屋屋主
  • 在Python程序中设置函数最大递归深度

    在函数调用时,为了保证能够正确返回,必须进行保存现场和恢复现场,也就是被调函数结束后能够回到主调函数中离开时的位置然后继续执行主调函数中的代码。这些现场或上下文...

    Python小屋屋主
  • Python+sklearn机器学习应该了解的33个基本概念

    机器学习(Machine Learning)根据已知数据来不断学习和积累经验,然后总结出规律并尝试预测未知数据的属性,是一门综合性非常强的多领域交叉学科,涉及线...

    Python小屋屋主
  • ubuntu18.04部署python3、nginx项目

    昨天服务器开了一个新管理员账号,用的弱口令,导致被黑了,ssh也不能登录,没办法,只能重装系统,还好没重要资料,服务器上只跑了一个公交的api和博客,早上重装了...

    青年码农
  • 原来这就是MapReduce!

    找到工作后的一小段时间是清闲的,小史把新租房收拾利索后,就开始找同学小赵,小李和小王来聚会了。

    Java3y
  • 【生活现场】从打牌到map-reduce工作原理解析

    找到工作后的一小段时间是清闲的,小史把新租房收拾利索后,就开始找同学小赵,小李和小王来聚会了。

    乔戈里
  • python高阶函数:map(f,[list]),reduce(f,[list],可选初始值),

    map,reduce和filter三个函数在python3和python2中发生了较大的差异。具体请看文章后面部分。 1. python的map()函数 ...

    学到老
  • python高阶函数:map(f,[list]),reduce(f,[list],可选初始值),

    map,reduce和filter三个函数在python3和python2中发生了较大的差异。具体请看文章后面部分。 1. python的map()函数 ...

    学到老
  • 必懂的NoSQL理论-Map-Reduce(下)

    本文主要内容:一开始我们会讨论把map-reduce切分成个两个阶段的内容,然后会说有关如何处理增量的基础理论。 上一文:必懂的NoSQL理论-Map-Redu...

    ImportSource
  • Python函数式编程-map/reduce

    map()函数接收两个参数,一个是函数,一个是Interable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

    yaohong

扫码关注云+社区

领取腾讯云代金券