《Python程序设计基础(第2版)》课件 05函数_第1页
《Python程序设计基础(第2版)》课件 05函数_第2页
《Python程序设计基础(第2版)》课件 05函数_第3页
《Python程序设计基础(第2版)》课件 05函数_第4页
《Python程序设计基础(第2版)》课件 05函数_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

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

文档简介

Python程序设计基础第5章函数教师:XXX第5章

函数5.1函数定义5.2函数调用与参数5.3变量的作用域5.4lambda表达式5.5生成器函数5.6函数递归调用5.7Python的第三方库5.1函数定义函数是完成特定功能的一段封装代码。Python可用的函数主要有三种来源:1.内置函数:位于python内核,启动python后就可直接使用的函数,如abs,max,len等。dir(__builtin__)#列出内置函数,第1个从abs开始2.模块内的函数:需先加载模块,再以"模块.函数"的形式调用。例如importmath;math.sqrt3.自定义函数:用户自行用def语句定义的函数,完成用户所需的特定功能。本章主要讨论此类函数。5.1函数定义功能独立且需多次执行的一组语句可作为一个整体封装起来形成一个函数。函数定义的一般形式为:def函数名(形参):'''函数说明部分'''#函数名下可附加一个可选的说明

函数体return值

defsquarediff(a,b): #定义平方差函数,a,b:形式参数'''功能:求平方差;a,b:浮点数'''d=a*a-b*breturndx=squarediff(5,3) #5,3实际参数print(squarediff(6,2))print(squarediff.__doc__) #输出函数说明部分函数命名要符合见名知义的原则。建议函数名下方附带一个简短的说明,该说明可用"函数.__doc__"的形式访问,便于了解函数功能。5.1函数定义函数可以没有参数,这样的函数称为无参函数。无参函数的定义形式为:def函数名():#即使无参,括号也不能省略

函数体defsayBye():#定义print('IlovePython')print("GoodBye!")for_inrange(3):sayBye()#调用5.1函数定义函数通过return语句返回计算结果。例如:使用return时注意如下3种情况:(1)return语句可省略。如没有return,则默认返回Nonedefwelcome():print("Welcome...")welcome()x=welcome()#无返回值,就不要写为变量=函数(),

会导致x为None例如列表排序lst.sort()方法就无返回值,不能写为lst=lst.sort()defmySum(a,b):'''计算并返回两个输入参数的和'''

returna+b5.1函数定义(3)多个return语句函数体中可以有多个return语句,当执行其中任意一个return语句后,该函数的执行就结束了。(2)return语句指定返回多个值函数也可返回多个值。将多个值放在return的后面,逗号分隔。defmulti(a,b):returna+b,a-b#实质是返回一个元组yz=multi(4,5)#yz=(9,-1)m,n=multi(4,5)#m=9,n=-1deffun(a,b): ifa<b: returnb-a elifa>b: returna-b return05.1函数定义为了给使用者明确的指引,函数定义时可用下面的语法说明参数与返回值的类型。在函数调用时起到提示作用,但非强制约束。defmySum(a:int,b:int)->int:#形参和返回值均为int型'''计算并返回两个整型参数的和'''returna+b调用自己编写的函数上面定义的若干函数假定保存在mytool.py源文件中,一个.py文件既是一个模块。若其它程序要调用此模块中的函数,需要先导入模块:importmytoolmytool.mySum(10,20)mytool.welcome()如要导入的模块文件不在当前目录或系统目录中,则可按如下方法设置模块搜索路径sys.path,该路径是目录列表,用于引导搜索模块。importsyssys.path.append('d:/tools')#假定mytool.py保存在d:/tools目录中importmytool#先添加搜索路径,再import,确保找到该模块5.2函数调用与参数5.2.1函数调用的一般形式函数调用的一般形式为:函数名(实际参数)注:函数调用时一定要有小括号。没有小括号不会报告语法错误,但这不是调用函数,相当于给函数一个别名。d=minus#缺失括号,相当于给minus起了个别名dc=d(8,3)#此处的d等同于minus函数defminus(a,b):#定义returna-bc=minus(8,3)#调用5.2函数调用与参数5.2.1

函数调用的一般形式函数调用时,暂停主程序执行,转去执行被调用函数。被调用函数执行完后返回原调用处继续向下执行。如下图:defcallee(): print("被调用函数执行")#主程序如下:print("调用函数之前")callee()print("调用函数之后")执行主程序的输出如下:5.2函数调用与参数5.2.2

不可变对象和可变对象参数Python数据类型分为不可变数据和可变数据。数值、字符串和元组是不可变对象;列表、集合和字典是可变对象(3.5节)。不可变是指不可修改原内存单元的数据。不可变对象作为函数实参时,如果在函数体内改变形参的值,不会导致实参值发生改变。defchange(a):a=a+1print("a=",a)b=4change(b)print("b=",b)#b的值不变输出如下:a=5b=45.2函数调用与参数可变对象作为函数实参时,在函数体内改变形参将导致实参发生改变。例如:程序的输出如下:defchangeList(a):foriinrange(len(a)):a[i]=a[i]*2print("a=",a)b=[1,2,3]print("b=",b)changeList(b)print("b=",b) #b被改变了5.2函数调用与参数5.2.3

默认值参数定义函数时,可以为形参设置默认值。设置默认值可以简化函数调用。Python的很多函数都有默认值参数。例如:int('11',base=10),sorted(lst,reverse=False)等。def函数名(…,形参名=默认值):

函数体defdefaultPara(a,b=1):print("a={},b={}".format(a,b))defaultPara(2) #调用,b未传值则取默认值defaultPara(2,3) #也可传值,则以实参为准定义默认值参数时,默认值参数的右边不能再出现没有默认值的参数。deff(x,y=10,z)#错误,y的右边不能再出现没有默认值的z5.2函数调用与参数5.2.4

关键字参数通过关键字(命名)参数,在调用时指定形参的名字,可以实现实参不按照形参的顺序书写,不用记忆形参顺序,调用格式易于理解。defkeyPara(a,b,c):print(a+b*c)print("a={},b={},c={}".format(a,b,c))keyPara(1,2,3)#如果keyPara(3,2,1)结果不同#使用关键字参数,按如下几种方式调用,效果相同:keyPara(a=1,b=2,c=3)keyPara(c=3,b=2,a=1)keyPara(1,b=2,c=3)keyPara(1,b=2,3)#这种格式错误,关键字参数后面不能再有位置参数5.2函数调用与参数5.2.5

不定长参数定义函数时如不能确定形参的数量,那么可定义不定长参数,这样增加了程序调用的灵活性。例max(2,5,10);max(1,10,5,20,9)不定长参数的定义形式有两种。第一种形式如下:def函数名(*形参名):#注意*表示不定长

函数体系统将传递进来的任意数量的实参组合成一个元组传给形参。defmySum(*p):print(type(p))#p实际为元组print(sum(p))mySum(1,3,5)mySum(2,4,6,8,10)5.2函数调用与参数第二种定义不定长参数的形式如下:def函数名(**形参名):#**视为字典

函数体系统将传递进来的任意数量的、显式赋值的关键字实参组合成一个字典传给形参。defvarPara(**p):foritinp.items():#p是字典print(it)varPara(a=1,b=2,c=3) #必须全部按关键字参数格式传递varPara(name='john',age=20,score=90)#varPara(1,b=2,c=3) #将报错,因为1不是关键字参数格式5.2函数调用与参数5.2.6

实参序列解包实参序列解包是指当函数具有多个形参时,可以使用列表、元组、集合及其他可迭代对象作为实参,并在实参名称前面加上一个星号*,Python将自动对实参序列解包,将序列中的值分别传递给形参。如果实参是字典,那么需加两个星号**。defvarPara(x,y,z):print("Thesumis{}".format(x+y+z))#以下两行代码实现对列表解包a=[1,2,3]varPara(*a)#个数要匹配,如写为varPara(a[0],a[1],a[2])较繁琐#varPara(a)#错误#以下两行代码实现对字典解包dic={'x':1,'y':2,'z':3}varPara(**dic)#要求字典的键名必须和形参名一致5.2函数调用与参数函数练习1.编写具有默认值参数的求和函数sum1,默认求[1,100]区间的和。2.编写不定长参数求平均值的函数avg。例如:#avg(1,2,3)#返回2.0,avg(2,4,6,8,10)#返回6.0defavg(*p):returnsum(p)/len(p)defsum1(m=1,n=100):returnsum(range(m,n+1))3.编写学生信息输出函数,可对传入的任何学生信息对进行输出。defoutstu(**di):fork,vindi.items():print(k,v)

outstu(id='1',name='张')outstu(classid='2',name='李',score=90)补充:函数参数中新增的特殊的/和*字符此处的/和*本身不是参数,但有特定含义:/表示/前面的参数a,b只能用位置参数,不能用关键字参数*表示*后面的参数d,e只能用关键字参数/和*中间的参数c用位置参数和关键字参数均可fun(1,2,3,d=4,e=5)#正确fun(1,2,3,4,5)#错误,*后面的参数d,e必须用关键字参数#错误,/前面的参数a,b必须是位置参数,不能是关键字参数形式fun(a=1,b=2,c=3,d=4,e=5)deffun(a,b,/,c,*,d,e):returna+b*c+d*e5.3变量的作用域变量作用域是指变量起作用的范围,它由定义变量的位置决定。不同作用域内的变量互不影响。变量分为局部变量和全局变量。局部变量是在函数内部赋值的变量,只在该函数内部起作用,作用范围从定义位置开始到函数结束。例如:deflocal():a=3 #局部变量print('local内a=',a) deffun():a=4 #局部变量print('fun内a=',a) local()fun()#print('主程序:',a) #将报错,主程序中无法访问局部变量a5.3变量的作用域全局变量是指在函数外部定义的变量,或是在函数内用global关键字特别申明的变量。其作用范围从定义该变量的位置开始到程序结束。例如:如果要在函数体内部修改全局变量a的值,那么要用关键字global申明变量a。例如:牢记:在函数内部被赋值,但又没有被global申明的变量都是局部变量。a=5 #全局变量defglob():b=a #使用了全局变量a,此处的b局部print("a={},b={}".format(a,b))glob()a=5defglob():globala #声明此处的a是全局变量a=4glob()print("a={}".format(a))#将输出a=45.3变量的作用域全局和局部概念练习defm():b.append(1)b=[]m()m()print(b)#输出?defm():globalbb=b+1b=2m();m()print(b)#输出?defm():

b=b+1#b局部b=2m();m()print(b)#为何报错?defm():c=b+1#b全局print(c)b=2m();m()5.4lambda表达式lambda表达式用于定义匿名函数。有时我们需要使用一个函数,但可能仅使用一次,在这种场合下,无需正式定义一个普通函数,用lambda定义一个匿名函数即可。格式为lambda形参:表达式fromrandomimportrandint,

seeddefst(x):returnx**2seed(1)a=[randint(-10,10)for_inrange(10)]#列表a含正数和负数print('排序前:',a)a.sort(key=st) #根据数据的平方值排序(方法1)a.sort(key=lambdax:x**2) #用lambda表达更简洁(方法2)print('排序后:',a)5.4lambda表达式#对学生列表排序的例子stu=[('B',90,85),('A',80,92),('C',85,85),('D',99,89)]s1=sorted(stu,key=lambdax:x[1]) #按成绩1排序s2=sorted(stu,key=lambdax:x[2]) #按成绩2排序s=sorted(stu) #按姓名字母排序也可以将lambda表达式变成命名函数,格式如下:

函数名=lambda形参:表达式f=lambdax,y:x+yprint(f(2,3))注意:lambda表达式很简单,只支持单条语句,不支持条件和循环。5.5生成器函数生成器函数是一种内含yield语句的特殊函数,用于创建生成器对象。生成器对象特点:1.惰性机制(数据延迟生成),2.节省内存。例如需产生10万个数据,普通函数要将10万个数据都产生并返回,内存耗费较大,而采用生成器对象可以每次只生成1个,处理后再生成下一个,节省内存。defg():#生成器函数a=1whileTrue:

yielda #利用yield关键字返回数据,不再使用returna=a+2

c=g()#c是生成器对象

print(type(c))#类型为generatorforiinrange(20):print(next(c),end='')#使用内建next函数获取数据,输出前20个奇数yield语句返回一个值并暂停函数的运行,下次通过内置函数next或for循环遍历生成器对象时再恢复执行,并从yield语句的后一条语句继续执行。5.5嵌套定义、修饰器和生成器函数练习:python原有的range函数不支持小数步长,要求自定义range2生成器函数,模仿range的工作方式并能支持小数步长。defrange2(start=0,stop=10,step=1):#生成器函数whilestart<stop:yieldstart

start=start+stepforxinrange2(1,5,0.5):print(x,end='')输出:5.6函数递归调用一个函数自己调用自己称为递归调用。利用递归可实现巧妙的算法设计。递归可分为:直接递归和间接递归。递归一定要注意终止递归的条件。直接递归就是一个函数直接调用该函数自身。如下:间接递归就是一个函数调用另一个函数,该函数又调用原函数。如下:deff():

g()

defg():

f()

deff():

f()

5.6函数递归调用【例1】编写递归函数,传入自然数n,返回其阶乘

n!。deff(n):ifn==1: return1 #不再递归returnn*f(n-1) #递归

n=eval(input("Inputaninteger:"))fac=f(n)print("{}!={}".format(n,fac))f(4)=4*f(3)f(3)=3*f(2)f(2)=2*f(1)f(1)=1类比数列anan-1an-2..a1,递归要正/反向递推两次注意:要防止无限递归maximumrecursiondepth5.6函数递归调用【例2】编写递归函数f(n),把十进制整数n转换为二进制数输出。分析:设整数n的二进制数为M,n//2的二进制数为N,则M=N*2+n%2。这样,就将求整数n的二进制数的问题分解为两个问题:求n//2的二进制数和求n%2。第二个问题比较简单,可以直接得到结果。第一个问题(求n//2的二进制数)与原问题有着相似的结构,即求一个整数的二进制数只是将整数变为原来的一半。因此,这个问题适合用递归的方法求解。deff(n):ifn==0:#当n为0或1时,无须再递归,可返回'0'或'1'return'0'elifn==1:return'1't=n%2#余数n=n//2#整除,得到nreturnf(n)+str(t)#递归调用n=eval(input("Inputaninteger:"))fac=f(n)print("{}={}".format(n,fac))5.6函数递归调用【例3】编写递归函数flat(*p,lst),将一个嵌套多层的可迭代对象p转为一维列表lst。fromcollections.abcimportIterable#引入可迭代类型Iterabledefflat(*p,lst):forxinp:ifisinstance(x,Iterable): #判断x是否是可迭代对象

flat(*x,lst=lst) #如是则实参序列解包,递归调用

else:lst.append(x)lst=[]data=[1,[[2,3],[4,5]],[[[6]]],range(7,9),(9,10)]#嵌套多层flat(*data,lst=lst)print(lst)列表、元组等都是可迭代的,用isinstance([4,5],Iterable)测试结果为True5.6函数递归调用递归练习:用递归写一个求和函数,可传入任意个数的参数。fromcollections.abcimportIterabledefsum2(*p):#第2版iflen(p)==0: return0else:ifisinstance(p[0],Iterable):#判断p[0]是否可迭代returnsum2(*p[0])+sum2(*p[1:])else:returnp[0]+sum2(*p[1:])defsum1(*p):#第1版iflen(p)==1: returnp[0]else:returnp[0]+sum1(*p[1:])注:sum1参数只能是数值,不能是列表和元组。sum1(3,4,5)#正确sum1(3,4,[5,6])#将报错注:sum2()参数可以是数值,列表,元组和range。例如sum2(1,[2,3],range(4,6))注:求和可看作第0个元素(p[0])加后面所有元素(p[1:])5.7Python的第三方库5.7.1

jieba库在进行文字分析时,分词是必做的工作。英文由于以空格为分隔,可以用s.split()分词,但split()无法对中文分词。jieba库的作用就是对中文文章进行分词,得到中文词语列表。安装命令如下:pipinstalljieba分词时cut()方法返回生成器对象,lcut()方法直接返回分词列表。cut_all=True表示全模式分词,字符串中的所有可能词语都会被提取出来。cut_all=False(默认)表示精确模式,只提取字符串中最长的词语。本节介绍Python程序设计二级考试要求的几个第三方库,以便掌握二级考试要求的考核内容importjiebas='我在北京大学'obj=jieba.cut(s,cut_all=False)#cut返回生成器对象,不是列表list(obj) #['我','在','北京大学']jieba.lcut(s,cut_all=True)#['我','在','北京','北京大学','大学']5.7Python的第三方库【例3】有字符串s,编程采用精确模式和HMM模型对该字符串进行分词,输出每个词及其在字符串中出现的频数,每个词只输出一次。importjiebas="编程语言可分为低级语言和高级语言,Python是高级语言。"lst=jieba.lcut(s,HMM=True)b=[]forvinlst: ifvnotinb: b.append(v) print(v,"\t",lst.count(v))lst内容如下,标点符号和空格都会占单独一项。['编程语言','可','分为','低级语言','和','高级','语言',',','Python','是','高级','语言','。']5.7Python的第三方库5.7.2

wordcloud库wordcloud库的功能是将一组给定的词语按照词频转换为一张词云图片,高频词占比较大,从而凸显文章大意。安装命令:pipinstallwordcloud使用wordcloud库来生成词云图,基本分三步:fromwordcloudimportWordCloud#注意大小写#第一步:构造一个WordCould对象wc=WordCloud(width=1000,height=800,background_color='white')#第二步:利用该对象的generate()方法生成词云图wc.generate(字符串s)#s必须是用空格分隔的串,例如'AA

BB

AA

CC'#第三步:利用该对象的to_file()方法将词云图保存为图片文件(png,jpg等)wc.to_file('tu.png')5.7Python的第三方库#英文词云图示例fromwordcloudimportWordClouds='Withtheimprovingofsemiconductortechnology,asinglechipintegratesmoreandmoreprocessingcores.Highlyparallelapplicationsaredistributedtotensofprocessingunits.Theinter-processorcommunicationdelaybecomesmoreandmoreimportantforparallelapplications.'wc=WordCloud(background_color='white',width=1000,height=800)wc.generate(s)wc.to_file('wc.png')#生成的图片默认保存在程序所在的目录#在IPython中执行下面命令可显示图片fromIPython.displayimportImageImage('wc.png')5.7Python的第三方库中文文章首先用jieba分词,再用空格连接分词,得到以空格分隔的字符串,然后用WordCloud生成词云,生成时要指定中文字体。importjiebastring='编写程序就是用计算机语言实现算法的过程。可以证明,任何问题都可以由三种基本结构表达出来。这三种基本结构包括顺序结构、选择结构和循环结构。'words=jieba.lcut(string)#先分词jbstr=''.join(words)#用空格将分词列表连接为字符串,''内有空格wc=WordCloud(font_path='simkai.ttf',background_color='white',width=500,height=400)#楷体,指定中文字体wc.generate(jbstr)#生成词云wc.to_file('wc2.png')#存为wc2.png5.7Python的第三方库5.7.4

turtle库turtle库是Python内含的一个简易绘图库,可直接使用。它通过模拟一只乌龟在画板上爬行来绘制图形,适合初学者练习编程。画板采用笛卡儿坐标系,原点(0,0)位于画板中央。初始,乌龟位于原点,朝向X轴的正方向(0度)。只需设定画笔的方向(常用seth/left/right)和前进距离(fd),就能沿指定方向绘制一条直线或曲线。距离单位为像素。#画一个边长200像素的矩形importturtleastfor_inrange(4):t.fd(200) #绘制200像素长的线条t.right(90) #每绘一条线就右转90度t.done() #结束绘图,spyder中需要此句turtle和Spyder不太兼容,运行时每两次会报一次Terminator错。同样的代码在IDLE中没问题。建议在IDLE中调试turtle代码。官方教程/3/library/turtle.html32145.7Python的第三方库5.7.4

turtle库(常用函数)forward()或fd():向前移动指定的距离,参数为数值,单位像素。backward()或bk():向后移动指定的距离。right()或rt():以

温馨提示

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

评论

0/150

提交评论