点击上方蓝字,和我一起学技术。今天是Python专题第6篇文章,给大家介绍的是Python当中三个非常神奇的方法:map、reduce和filter。不知道大家看到map和reduce的时候有没有什么感觉,如果看过之前我们大数据系列介绍MapReduce文章的同学,想必有些印象。这个MapReduce不是一个分布式的计算方法么,怎么又变成Python中的方法了?其实原因很简单,因为Python是一门很年轻的语言,它在发展的过程当中吸收了很多其他领域的精华,MapReduce就是其中之一。对之前文章感兴趣的同学可以点击下方的链接,回顾一下之前MapReduce的内容。

大数据基石——Hadoop与MapReduce

map

map除了地图之外,另一个英文本意是映射。在C++和Java一些语言当中,将map进一步引申成了存储key和value映射结构的容器。Python对这点做了区分,KV结构的容器命名成了dict,即字典,而map则回到了它的本意,也就是映射。我们都知道,在数学领域,映射也是函数的定义。一个自变量通过某种映射,对应到一个因变量。同样,在Python当中,map操作本质也是函数,不过它作用的范围不再是单个变量,而是一个序列。换句话说,通过map我们可以省去循环操作,可以自动将一个容器当中的元素套用一个函数。


举个简单的例子,比如我们有一个坐标,我们希望知道它距离原点的距离。这个问题很简单,我们写一个计算距离的函数就可以解决:

def dis(point):return math.sqrt(point[0]**2 + point[1]**2)

那如果我有多个点需要计算距离,在map出现之前,我们只能用循环来解决问题:

points = [[0, 1], [2, 4], [3, 2]]for point in points:    print(dis(point))

但是有了map之后, 我们可以省去循环的操作,整个代码简化成了一行:

map(dis, points)

但是要注意,我们调用完map之后得到的结果不是一个list而是一个迭代器。我们直接将map返回的内容print出来,可以得到这样一个结果:

>>> print(map(dis, points))0x107aad1d0>

这是一个类的标准输出,其实它返回的不是最后的结果,而是一个迭代器。我们在之前的文章当中已经介绍过了迭代器和生成器的相关概念,这里不多做赘述了,遗忘的同学可以点击下方链接回顾一下之前的内容:

Python——五分钟带你弄懂迭代器与生成器,夯实代码能力

我们想要获得完整的内容也很容易,我们只需要将它转化成list类型即可:

>>> print(list(map(dis, points)))[1.0, 4.47213595499958, 3.605551275463989]

以上过程还可以进一步简化,还记得我们之前介绍过的匿名函数吗?由于dis函数在我们的程序当中只会在map中用到,我们完全没有必要单独创建一个函数,我们可以直接传入一个匿名函数搞定运算:

map(lambda x: math.sqrt(x[0]**2 + x[1] ** 2), points)

简单总结一下,map操作其实执行的是一个映射。它可以自动地将一个序列当中的内容通过制定的函数映射成另一个序列,从而避免显式地使用循环来调用,在很多场景下可以大大地简化代码的编写,可以很方便地将一个序列整体转变成另一个结果。

reduce

相比于map,reduce的操作稍稍难理解一点点。它也是规定一个映射,不过不是将一个元素映射成一个结果。而是将两个元素归并成一个结果。并且它并不是调用一次,而是依次调用,直到最后只剩下一个结果为止。比如说我们有一个数组[a, b, c, d]和一个函数f,我们计算reduce(f, [a, b, c, d])其实就等价于f(f(f(a, b), c), d)。和map不同的是,reduce最后得到一个结果,而不是一个迭代器或者是list。我们光说有些抽象,不妨来看一个例子,就看最简单的一个例子:reduce函数接收两个数,返回两个数的和。那么显然,我们依次调用reduce,得到的就是原数组的和。

from functools import reducedef f(a, b):return a + bprint(reduce(f, [1, 2, 3, 4]))

最终得到的结果当然是10,同样,我们也可以将reduce中的方法定义成匿名函数,一样不影响最终的结果。

print(reduce(lambda x, y: x + y, [1, 2, 3, 4]))

MapReduce

既然我们map和reduce都有了,显然我们可以将它们串联起来使用,也就是分布式系统当中MapReduce的做法。虽然如果不手动使用线程池的话,Python并不会起多个线程来加速运算,但是至少可以简化我们实现的代码。我们还是举经典的wordCount的例子,也就是文本计算词频。套用map和reduce的功能,整个流程非常清晰,我们只需要在map阶段对文本进行分词,在reduce阶段对分词之后的结果进行汇总即可。听着好像非常容易,但是你实际去上手是写不出来的。原因也很简单,因为hadoop当中的Map和Reduce中间还有一层shuffle的操作,会自动地将key值相同的结果放到同一个reducer当中。在这个问题当中,key自然就是我们的word,由于相同的word被放到同一个reducer当中,我们只需要累加就行了。但是如果我们自己编写mapreduce的话,由于缺少了中间数据重排的步骤,所以导致不能实现。要解决也简单,我们可以人为增加一个map阶段代替hadoop当中的重排。相当于做了一个MapMapReduce,我们来看代码:

from collections import Counter, defaultdicttexts = ['apple bear peach grape', 'grape orange pear']# 第一次map,将字符串转成数组,每个单词对应1def mp1(text):    ret = []    words = text.split(' ')for word in words:        ret.append((word, 1))return ret# 第二次map,将数组转成dictdef mp2(arr):    d = defaultdict(int)for k, v in arr:        d[k] += vreturn d# reduce,合并dictdef rd(x, y):    x.update(y)return xprint(reduce(rd, map(mp2, map(mp1, texts))))

那如果我们不用多次MapReduce呢?也不是没有办法,需要取点巧,方法也简单只要使用之前我们讲解过的Counter类,就可以完美解决这个问题。我们来看代码:

from collections import Countertexts = ['apple bear peach grape', 'grape orange pear']def mp(text):    words = text.split(' ')return Counter(words)print(reduce(lambda x, y: x + y, map(mp, texts)))

由于我们使用了Counter,所以我们在map阶段返回的结果就已经是词频的dict了,而在reduce阶段我们只需要将它们全部累加起来就OK了。最后,我们来看下filter

filter

filter的英文是过滤,所以它的使用就很明显了。它的用法和map有些类似,我们编写一个函数来判断元素是否合法。通过调用filter,会自动将这个函数应用到容器当中所有的元素上,最后只会保留运行结果是True的元素,而过滤掉那些是False的元素。举个例子,假设我们想要保留list当中的奇数而过滤掉偶数,我们当然可以直接操作,比如:

arr = [1, 3, 2, 4, 5, 8][i for i in arr if i % 2 > 0 ]

而使用filter会非常方便:

list(filter(lambda x: x % 2 > 0, arr))

从这个例子当中可能看不出便捷,但是有的时候判断的条件可能非常复杂,我们判断的逻辑不能简单地在list定义当中表达出来,这个时候使用filter则会容易得多。最后, 我们再看一个类似的用法。在itertools当中有一个方法叫做 compress,通过compress我们可以实现根据一个序列的条件过滤另一个序列。举个简单的例子,假设,我们有两个数组:

student = ['xiaoming', 'xiaohong', 'xiaoli', 'emily']scores = [60, 70, 80, 40]

我们想要获取所有考试及格的同学的list,如果用常规做法基本上免不了使用循环,但是使用compress可以很方便地通过一行代码实现:

from itemtools import compress>>> pass = [i > 60 for i in scores]>>> print(pass)[False, True, True, False]>>> list(compress(student, pass))['xiaohong', 'xiaoli']

需要注意的是filter和compress返回的都是一个迭代器,我们要获取它们的值,需要手动转换成list。虽然在日常的开发当中不使用这三样神器同样可以工作,但是用上它们之后,会提升很多代码的可读性,节省很多无用的代码。尤其是在面试的时候,很有可能就会给面试官留下不一样的印象,也许结果也会不同。今天的文章就是这些,如果觉得有所收获,请顺手点个在看或者转发吧,你们的举手之劳对我来说很重要。

c++ map用法_Python专题——五分钟带你了解map、reduce和filter相关推荐

  1. 五分钟学会python函数_五分钟带你搞懂python 迭代器与生成器

    前言 大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法.对于获取数据的方法而言,我们会一种就 ...

  2. 干货:五分钟带你看懂NestedScrolling嵌套滑动机制

    Android NestedScrolling嵌套滑动机制 Android在发布5.0之后加入了嵌套滑动机制NestedScrolling,为嵌套滑动提供了更方便的处理方案.在此对嵌套滑动机制进行详细 ...

  3. python map用法_Python中 map()函数的用法详解

    python map()函数问题 使用map()函数生成一个值D但是检测D的长度时,只能测一次,一次之后D似不知道你的dataSet 是什么数据,是否是从数据库取出来的结果游标, 如果是的 那么dat ...

  4. map 长度_Python实用教程系列——高阶函数Map、Filter、Reduce

    点击上方蓝色文字关注我们吧 有你想要的精彩 作者 | 那个百分十先生出品 | Python知识学堂 上次推文我们介绍了python中的<Logging日志模块>的相关知识,这次推文我们将学 ...

  5. c++ map用法_Python的 5 种高级用法,效率提升没毛病

    原创:机器之心(ID:almosthuman2014) 任何编程语言的高级特征通常都是通过大量的使用经验才发现的.比如你在编写一个复杂的项目,并在 stackoverflow 上寻找某个问题的答案.然 ...

  6. 二道波哥-五分钟带你了解好省

    什么是好省? 1.好省是一款导购APP,依托于淘宝天猫平台,为广大用户提供海量优惠券,致力于帮助用户买到最具性价比的网购商品.与此同时,好省还是一个创业平台,在这里,任何人都可以0门槛.0投资创业,只 ...

  7. 五分钟带你玩转Zabbix6.0容器化HA集群

    图片 蔡斯 | Zabbix开源社区签约专家 Zabbix资深玩家,SRE高级运维,架构师.精通服务组件监控.模板制作及告警治理. 擅长领域:Zabbix API定制化开发,对接企业蓝鲸,JMS保垒机 ...

  8. c语言实现java接口_五分钟带你了解Java是如何从容而优雅地实现接口数据校验

    本篇文章给大家分享平时开发中总结的一点小技巧!在工作中写过Java程序的朋友都知道,目前使用Java开发服务最主流的方式就是通过Spring MVC定义一个Controller层接口,并将接口请求或返 ...

  9. 五分钟带你了解Django框架设计思想!

    Python编程语言的持续火爆,在最新Tiobe编程语言排行榜中位列第五,热度持续增加,尤其是在 AI 和 大数据时代,Python是 AI 和大数据时代的第一开发语言.这已经是一个不争的事实了,唯一 ...

最新文章

  1. Android中设置控件可见与不可见详解
  2. 波士顿动力的机器狗上班了!巡逻、检测不在话下,挪威公司为其编发工号
  3. lua sleep函数实现
  4. mac电脑开机键盘和鼠标失灵
  5. P2305 [NOI2014] 购票(点分治、斜率优化)
  6. React脚手架学习笔记
  7. 洪筱楠(1996-),女,对外经济贸易大学国际经济贸易学院经济学荣誉学士实验班本科生。...
  8. 解决Windows 7 系统,Group Policy Client 服务未启动,不能登录的问题。
  9. mysql zip win10安装_mysql 8.0.16 Win10 zip版本安装配置图文教程
  10. 菁英班OJ赛2022-2-24(第一周)
  11. thinkphp系统常量与自定义常量
  12. 58条模拟、数字电路基础知识总结
  13. ubuntu16.04系统下配置caffe的GPU环境,训练mobileNet-SSD并在EAIDK-310嵌入式上推理
  14. 利用tushare数据计算期货主力合约的活跃度
  15. 一个强悍的算24点游戏的PHP程序
  16. Ubuntu Qt项目编译提示 cannot find -lGL
  17. 【无标题】打印水仙花(pyth)
  18. javascript招式总结
  19. 永久开源的cms系统
  20. 网优5g前景_5G网络优化工程师的前景和待遇

热门文章

  1. 【Python】判断是否为 None
  2. 【Matlab】定义顺序增加的字符串数组(A1,A2 ... An)并写到Excel的第一行
  3. 【Matlab】怎么修改Excel单元格颜色?
  4. [云炬创业基础笔记]第一章创业环境测试3
  5. 燃烧学往年精选真题解析
  6. 十、“月非空中月,无缺亦无圆”(2021.1.15)
  7. 第17课:循环神经网络(RNN)
  8. 重磅 | AI 圣经 PRML《模式识别与机器学习》官方开源了!
  9. 30岁面霸IT男30次面试失败经历
  10. C++字符串处理操作符重载