Python基础教程(第3版)- 课件 第7章 函数式编程_第1页
Python基础教程(第3版)- 课件 第7章 函数式编程_第2页
Python基础教程(第3版)- 课件 第7章 函数式编程_第3页
Python基础教程(第3版)- 课件 第7章 函数式编程_第4页
Python基础教程(第3版)- 课件 第7章 函数式编程_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Python程序设计授课教师:第7章函数式编程课程描述函数式编程是一种典范。本章首先对函数式编程的基本概念进行介绍,然后介绍Python语言是如何实现函数式编程的。本章知识点7.1函数式编程概述7.2Python函数式编程常用的函数7.3闭包函数7.4迭代器和生成器7.1函数式编程概述7.1.1函数式编程的概念7.1.2函数式编程的优点7.1.1函数式编程的概念函数式编程是一种编程的基本风格,也就是构建程序的结构和元素的方式。函数式编程将计算过程看作是数学函数,也就是可以使用表达式编程。在函数的代码中,函数的返回值只依赖传入函数的参数,因此使用相同的参数调用函数2次,会得到相同的结果。1.头等函数(First-classfunction)如果一个编程语言把函数视为头等函数,则可以称其拥有头等函数。拥有头等函数的编程语言可以将函数作为其他函数的参数,也可以将函数作为作为其他函数的返回值。可以把函数赋值给变量或存储在元组、列表、字典、集合等数据结构中。在拥有头等函数的编程语言中,函数名没有任何特殊的状态,而是将函数看作是function类型的二进制类型。2.高阶函数(Higher-orderfunction)高阶函数是头等函数的一种实践,它是可以将其他函数作为参数或返回结果的函数。例如,定义一个高阶函数map(),有2个参数,一个是函数func(),一个是列表list,map()函数将list里面的所有元素应用函数func(),并将处理结果组成一个列表list1,最后将list1作为map()函数的返回结果。3.纯函数纯函数具有如下特性:纯函数与外界交换数据只有唯一渠道——参数和返回值。纯函数不操作全局变量,没有状态、无I/O操作,不改变传入的任何参数的值。理想情况下,不会给他传入任何外部数据。很容易把一个纯函数移植到一个新的运行环境,最多只需要修改类型定义即可。纯函数具有引用透明性(ReferentialTransparency)。也就是说,对于同一个输入值,它一定得到相同的输出值,而与在什么时候、在什么情况下执行该函数无关。7.1.2函数式编程的优点1.便于进行单元测试2.便于调试3.适合并行执行7.2Python函数式编程常用的函数7.2.1lambda表达式7.2.2map()函数7.2.3filter()函数7.2.4reduce()函数7.2.5zip()函数7.2.6普通编程方式与函数式编程的对比7.2.1lambda表达式lambda函数也是一种匿名函数,是从数学里的λ演算得名的。λ演算可以用来定义什么是一个可计算函数。匿名函数并非没有名字,而是将函数名作为函数结果返回。1.lambda函数Python的lambda表达式的函数体只能有唯一的一条语句,也就是返回值表达式语句。其语法如下:返回函数名=lambda参数列表:函数返回值表达式语句例如,下面的lambda表达式可以计算x、y和z等3个参数的和:sum=lambdax,y,z:x+y+z可以使用sum(x,y,z)调用上面的lambda表达式。【例7-1】使用lambda表达式的例子。sum=lambdax,y,z:x+y+zprint(sum(1,2,3))运行结果为:6【例7-1】中的lambda表达式相当于下面的函数。defsum(x,y,z): returnx+y+z2.lambda表达式序列可以将lambda表达式作为序列(如列表、元组或字典等)元素,从而实现跳转表的功能,也就是函数的列表。lambda表达式序列的定义方法如下:序列名=[(lambda表达式1),(lambda表达式2),…]调用序列中lambda表达式的方法如下:序列名[索引](lambda表达式的参数列表)【例7-2】定义一个lambda表达式序列。第1个元素用于计算参数的平方,第2个元素用于计算参数的立方,第3个元素用于计算参数的四次方。代码如下:Arr=[(lambdax:x**2),(lambdax:x**3),(lambdax:x**4)]print(Arr[0](2),Arr[1](2),Arr[2](2))程序分别计算并打印2的平方、立方和四次方。运行结果如下:48163.将lambda表达式作为函数的返回值可以在普通函数中返回lambda表达式。【例7-3】定义一个函数math。当参数o等于1时返回计算加法的lambda表达式;当参数o等于2时返回计算计算减法的lambda表达式;当参数o等于3时返回计算乘法的lambda表达式;当参数o等于4时返回计算除法的lambda表达式。代码如下:defmath(o):if(o==1):returnlambdax,y:x+yif(o==2):returnlambdax,y:x-yif(o==3):returnlambdax,y:x*yif(o==4):returnlambdax,y:x/yaction=math(1)#返回加法lambda表达式print("10+2",action(10,2))action=math(2)#返回减法lambda表达式print("10-2=",action(10,2))action=math(3)#返回乘法lambda表达式print("10*2,=",action(10,2))action=math(4)#返回除法lambda表达式print("10/2,=",action(10,2))【例7-3】运行结果如下:10+21210-2=810*2,=2010/2,=5.07.2.2map()函数map()函数用于将指定序列中的所有元素作为参数调用指定函数,并将结果构成一个新的序列返回。map函数的语法如下:结果序列=map(映射函数,序列1[,序列2,…])在map()函数的参数中,可以有多个序列,这取决于映射函数的参数数量。序列1、序列2等序列中元素会按顺序作为映射函数的参数,映射函数的返回值将作为map()函数的返回序列的元素。【例7-4】使用map()函数依次计算2、4、6、8和10的平方。arr=map(lambdax:x**2,[2,4,6,8,10])foreinenumerate(arr):print(e)本例中映射函数是一个lambda表达式,用于计算参数的平方。因为映射函数只有1个参数,所以map()函数中只有1个序列参数。map()对序列参数应用lambda表达式,将计算结果作为序列返回。【例7-4】运行结果如下:(0,4)(1,16)(2,36)(3,64)(4,100)【例7-5】在map()函数中对两个序列进行处理。arr=map(lambdax,y:x+y,[1,3,5,7,9],[2,4,6,8,10])foreinenumerate(arr):print(e)本例中映射函数是一个有2个参数的lambda表达式,用于计算参数之和。因为映射函数有2个参数,所以map()函数中有2个序列参数。map()对2个序列参数中对应位置的元素应用lambda表达式,将计算结果作为序列返回。【例7-5】运行结果如下:(0,3)(1,7)(2,11)(3,15)(4,19)7.2.3filter()函数filter()函数可以对指定序列执行过滤操作,具体定义如下:filter(函数function,序列sequence)函数function接受一个参数,返回布尔值True或False。序列sequence可以是列表、元组或字符串。filter()函数以序列sequence中的每个元素为参数调用function函数,调用结果为True的元素最后将作为filter()函数的结果返回。【例7-6】使用filter()函数的例子。defis_even(x): returnx%2==0arr=filter(is_even,[1,2,3,4,5,6,7,8,9,10])foreinenumerate(arr):print(e)【例7-6】运行结果如下:(0,2)(1,4)(2,6)(3,8)(4,10)7.2.4reduce()函数reduce()函数用于将指定序列中的所有元素作为参数,按一定的规则调用指定函数。reduce函数的语法如下:计算结果=reduce(映射函数,序列)映射函数必须有2个参数。reduce()函数首先以序列的第1和第2个元素为参数调用映射函数,然后将返回结果与序列的第3个元素为参数调用映射函数。以此类推,直至应用到序列的最后一个元素,将计算结果作为reduce()函数的返回结果。【例7-7】使用reduce()函数计算2、4、6、8、10的和。fromfunctoolsimportreducedefmyadd(x,y):returnx+ysum=reduce(myadd,(2,4,6,8,10))print(sum)【例7-7】程序运行过程:(1)reduce()函数首先使用2和4为参数调用myadd()函数,得到结果6。(2)使用结果6和序列的第3个元素6为参数调用myadd()函数,得到结果12。(3)使用结果12和序列的第4个元素8为参数调用myadd()函数,得到结果20。(4)使用结果20和序列的第5个元素10为参数调用myadd()函数,得到结果30。7.2.5zip()函数zip()函数以一系列列表作为参数,将列表中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。【例7-8】使用zip()函数的例子。a=[1,2,3]b=[4,5,6]zipped=zip(a,b)forelementinzipped:print(element)【例7-8】运行结果如下:(1,4)(2,5)(3,6)【例7-9】使用zip()函数时传入参数长度不等的例子。a=[1,2,3]b=[4,5,6,7,8,9]zipped=zip(a,b)forelementinzipped:print(element)注意:调用zip()函数时以长度最短的列表长度为基准进行压缩。【例7-9】运行结果如下:(1,4)(2,5)(3,6)7.2.5zip()函数将打包结果前面加上操作符*,并以此作为参数调用zip()函数,可以将打包结果解压。【例7-10】使用zip()函数将打包结果解压的例子。a=[1,2,3]b=[4,5,6]zipped=zip(a,b)unzipped=zip(*zipped)forelementinunzipped:print(element)【例7-10】运行结果如下:(1,2,3)(4,5,6)7.2.6普通编程方式与函数式编程的对比【例7-11】以普通编程方式计算列表元素中正数之和。list=[2,-6,11,-7,8,15,-14,-1,10,-13,18]sum=0foriinrange(len(list)):iflist[i]>0:sum+=list[i]print(sum)运行结果如下:647.2.6普通编程方式与函数式编程的对比【例7-12】以函数式编程方式实现【例7-11】的功能。fromfunctoolsimportreducelist=[2,-6,11,-7,8,15,-14,-1,10,-13,18]sum=filter(lambdax:x>0,list)s=reduce(lambdax,y:x+y,sum)print(s)7.2.6普通编程方式与函数式编程的对比相比而言,函数式编程具有如下特点:(1)代码更简单。(2)数据,操作,返回值都放在一起。(3)没有循环体,几乎没有临时变量,也就不用劳神去分析程序的流程行尾数据变化过程。(4)代码用来描述要做什么,而不是怎么去做。7.3闭包函数在Python中,闭包指函数的嵌套。可以在函数内部定义一个嵌套函数,将嵌套函数视为一个对象,所以可以将嵌套函数作为定义它的函数的返回结果。闭包的基本形式是:在函数F1中,定义F2,F2只能引用F1定义的变量,之后F1函数返回F2的函数名字。而后可以将F1的执行结果赋给一个新的函数名,该函数可以在之后随时执行。

7.3闭包函数在Python中,闭包所需要具备的条件:必须有一个嵌套函数。嵌套函数必须引用外部函数中的变量。外部函数必须将嵌套函数作为返回值返回。【例7-13】使用闭包的例子。deffunc_lib():defadd(x,y):returnx+yreturnadd#返回函数对象fadd=func_lib()print(fadd(1,2))运行结果:37.4迭代器和生成器7.4.1迭代器7.4.2生成器7.4.1迭代器迭代器是访问序列内元素的一种方式。迭代器对象从序列(列表、元组、字典、集合)的第一个元素开始访问,直到所有的元素都被访问一遍后结束。迭代器不能回退,只能往前进行迭代。1.iter()函数使用iter()函数可以获取序列的迭代器对象,方法如下:

迭代器对象=iter(序列对象)使用next()函数可以获取迭代器的下一个元素,方法如下:

next(迭代器对象)

如果所有元素均已经返回过,则抛出StopIteration异常。【例7-14】使用iter()函数的例子。list=[111,222,333]it=iter(list)print(next(it))print(next(it))print(next(it))运行结果如下:1112223332.enumerate()函数使用enumerate()函数可以将列表或元组生成一个有序号的序列。【例7-15】使用enumerate()函数的例子。list=[111,222,333]forindex,valinenumerate(list):print("第%d个元素是%s"%(index+1,val))运行结果如下:第1个元素是111第2个元素是222第3个元素是3337.4.2生成器生成器是一个特殊的函数,它具有如下特点:(1)生成器

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论