Python程序设计基础教程课件 第12章 函数_第1页
Python程序设计基础教程课件 第12章 函数_第2页
Python程序设计基础教程课件 第12章 函数_第3页
Python程序设计基础教程课件 第12章 函数_第4页
Python程序设计基础教程课件 第12章 函数_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

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

文档简介

Python程序设计基础教程

第12章函数提纲函数概述参数传递和返回值实参和形参名字空间装饰器lambda表达式高阶函数递归函数学习目标使用def语句定义函数函数定义时的默认值参数、可变长度的位置和关键字参数通过位置参数和关键字参数传递以及序列解包等方式调用函数掌握名字的作用域以及global语句和nonlocal语句了解闭包的概念,如何使用和实现装饰器掌握如何使用lambda表达式定义匿名函数掌握map(.)、filter(.)和reduce(.)函数使用内置函数sorted(.)进行排序掌握生成器函数掌握递归函数12.1函数概述函数定义和调用def语句定义函数函数体在函数头部的下一行,一般整体缩进4个空格如果函数体非常简单,特别是只有一条语句时,也允许与函数头部在同一行创建一个函数对象。def语句描述的函数体代码、文档字符串、缺省值和闭包等信息保存在函数对象中当前名字空间引入一个名字与新创建的函数对象绑定deffuncname(parameter_list):suitefuncname(argument_list)deff(x):

"""上述数学函数f(x)的实现"""

ifx>=0:

returnx**2

else:

return-x

t=f(2)

函数定义函数是一个一等对象文档字符串:函数体的第一个语句为字符串字面量,该字符串保存在函数对象的__doc__属性中Python源程序的第一个语句为字符串字面量时,该字符串会保存在变量__doc__中defdistance(x,y):

"""返回直角坐标系中点(x,y)到原点的距离

传递的参数:x,y为点的X轴和Y轴坐标"""x2=x*xy2=y*y

return(x2+y2)**0.5func=distancefunc(1,1)#等价于调用distance(1,1)>>>help(distance)Helponfunctiondistanceinmodule__main__:

distance(x,y)

返回直角坐标系中点(x,y)到原点的距离

传递的参数:x,y为点的X轴和Y轴坐标函数的优点提高代码的重用性提高代码的可维护性提高代码的可读性pass:空语句defprepare():

"""从文件中读取相应的数据"""

defcalc(data):

pass

defoutput_result(result):

pass

if__name__=='__main__':data=prepare()result=calc(data)output_result(result)12.2参数传递和返回值赋值传递函数调用时创建一个新的名字空间参数传递:本地名字空间的形参变量=调用者传递的实参对象defmodify_mutable(v,item):

if

notv:v.append(1)

else:v[0]=v[0]+1v.append(item)item=item+1

v=[]t=1modify_mutable(v,t)modify_mutable(v,t)print(v,t)#v变为[2,1,1],t仍然为1return语句函数体执行到return语句,结束这次函数调用,将return语句后面给出的表达式计算后的对象返回给调用者return语句中后面没有表达式,则等价于returnNone如果函数体执行完毕,隐含returnNone返回None,一般也意味着该函数的返回值没有什么特殊的意义区分函数的返回值以及函数体通过print函数输出值return[expression]defmax1(x,y):

ifx>y:

returnx

else:

returny#在交互式控制台执行>>>max1(2,4)4>>>max2(2,4)4defmax2(x,y):

ifx>y:print(x)

else:print(y)函数的3个基本要素传递的参数返回的对象要完成的功能:函数调用者把函数看成一个黑盒子,不用关注内部的实现细节,只要传递相应的参数,就应该完成相应的功能,最后返回一个对象。函数的实现者关注的是如何实现这个黑盒子,每个参数是什么,怎么使用这些参数实现功能函数定义时,只是创建了一个函数对象函数调用时,才真正执行函数体的代码12.3实参和形参函数调用的参数位置实参:基于位置传递值关键字实参:基于参数名字传递值关键字参数右边不能有位置参数,即调用时参数的顺序为位置参数(如果有)、关键字参数deffunc1(a,b,c,d):print(a,b,c,d)

func1(1,2,3,4)func1(a=1,b=2,c=3,d=4)func1(b=2,a=1,d=4,c=3)func1(1,2,c=3,d=4)函数定义时的参数:位置参数和默认值参数位置参数:仅包含形参名的参数默认值参数:arg=default,arg为形参的名字,而default为一个表达式没有传递值时,该形参对应的是在函数定义时指定的默认值对象保存在函数对象的属性__defaults__中默认值参数右边不能再有普通的位置参数函数定义时可包含位置形参和默认值形参函数调用时可通过位置实参和关键字实参传递参数默认值形参和关键字实参的语法类似,相互独立的,没有必然的联系。x=5deff1(a,x=x,y=x+5):print(a,x,y)print(f1.__defaults__)#输出(5,10)deff(a,x=0,y=1,z):

#异常SyntaxError:non-defaultargumentfollowsdefaultargumentprint(a,x,y,z)deffunc2(a,b,c,x='x',y='y'):print(a,b,c,x,y)

#在交互式控制台执行>>>func2(1,2)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:func2()missing1requiredpositionalargument:'c'>>>func2(1,2,3)123xy>>>func2(1,2,3,4)1234y>>>func2(1,2,3,4,5)12345>>>func2(1,2,3,4,5,6)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:func2()takesfrom3to5positionalargumentsbut6weregiven>>>func2(1,2,3,y=5)123x5>>>func2(b=2,a=1,c=3,y=5)123x5>>>func2(1,b=2,c=3,x=5)1235y>>>func2(1,2,b=2,x=5)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:func2()gotmultiplevaluesforargument'b'函数定义时的参数:默认值为可变对象如果默认值参数的默认值为可变对象函数体有可能原地操作修改该可变对象,有时故意这样设计Python社区一般建议默认值参数的默认值采用不可变对象,避免采用可变对象defappend_item(item,old_list=[]):old_list.append(item)

returnold_list

deftest_append_item():print(append_item(5,[1,2,3,4]))print(append_item(1))#输出[1]print(append_item.__defaults__)#输出([1],)print(append_item(1))#输出[1,1]print(append_item.__defaults__)#输出([1,1],)

test_append_item()

defappend_item2(item,old_list=None):

ifold_listisNone:old_list=[]old_list.append(item)

returnold_list函数定义:可变长度参数可变长位置参数(*args),调用时那些尚未匹配形参的位置实参组合成1个元组,赋值给args可变长关键字参数(**kwargs),函数调用时那些尚未匹配形参的关键字实参组合成一个字典赋值给kwargs关键字参数name=obj,对应字典中的元素'name':obj最多只能有一个可变长位置参数,出现在位置参数和默认值参数(如果有)之后最多只能有一个可变长关键字参数,出现在最后形参和实参的匹配规则:首先按照位置匹配形参中的位置参数和默认值参数接下来根据关键字参数的名字匹配形参中的各个参数函数定义中,如果有尚未匹配的形参,且为默认值参数,将该形参设置为默认值如果有可变长度位置参数,将剩下的位置参数组成元组赋值给该参数如果有可变长度关键字参数,将剩下的关键字参数组成字典赋值给该参数如果仍然有尚未匹配的形参和实参则报错每个形参只能匹配一次。一个也不能少,一个也不能多,而且也不能重复匹配函数定义:可变长度参数defvariable_parameter(a,b=4,*x,**y):

returna,b,x,y

#在交互式控制台执行>>>variable_parameter(1)(1,4,(),{})>>>variable_parameter(1,2)(1,2,(),{})>>>variable_parameter(1,2,3,4,5)(1,2,(3,4,5),{})>>>variable_parameter(1,b=2,u=11,v=12,w=13)(1,2,(),{'u':11,'v':12,'w':13})>>>variable_parameter(1,2,3,4,5,u=11,v=12,w=13)(1,2,(3,4,5),{'u':11,'v':12,'w':13})函数定义:仅允许关键字参数传递的参数出现在可变长度位置参数之后的参数如果没有可变长度位置参数,额外添加一个参数*仅允许关键字参数传递的形参可以指定默认值,也可以不指定默认值defkwonly(a,*b,c,d=5,e):

returna,b,c,d,e

defkwonly2(a,b,*,c,d=5):

returna,b,c,d

#在交互式控制台执行>>>kwonly(1,2,c=3,e=4)(1,(2,),3,5,4)>>>kwonly2(1,2,c=3,d=4)(1,2,3,4)>>>kwonly2(a=1,b=2,c=3,d=4)(1,2,3,4)函数定义:仅允许位置参数传递的参数如果某个参数为/,表示该位置之前的所有参数都只能通过位置参数传递一般用于API函数的定义:参数的名字不会被用来通过关键字参数传输,可改名>>>help(divmod)Helponbuilt-infunctiondivmodinmodulebuiltins:

divmod(x,y,/)Returnthetuple(x//y,x%y).Invariant:div*y+mod==x.

>>>divmod(x=10,y=3)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:divmod()takesnokeywordarguments函数定义时的参数所有位置参数(包括仅位置参数传递的参数)可以有默认值,也可以没有默认值一旦某个参数有默认值,则其后续的参数不再允许有非默认值的位置参数仅关键字参数传递的参数:可以有默认值,也可以没有默认值,没有任何限制deffunc(pos1,pos2=2,/,pk1='pk1',pk2='pk2',*args,kw1='kw1',kw2,**kwargs):

returnpos1,pos2,pk1,pk2,args,kw1,kw2,kwargs函数调用的序列解包函数调用中,如果某个参数为*expr首先对expr进行求解,要求其为可迭代对象将可迭代对象中的元素展开,变成位置参数映射解包:如果某个参数为**expr,expr为可映射(比如字典)的对象将该对象中的元素展开,变成关键字参数key:value:要求key为字符串类型,且其包含的内容为合法的变量名'name':value展开为name=values=range(1,10)print(*s,sep='+',end='=')print(sum(s))#输出:1+2+3+4+5+6+7+8+9=45s=range(1,10)d={'sep':'+','end':'='}print(*s,**d)print(sum(s))可变长参数与序列解包在函数调用时,序列和映射解包用于将可迭代对象或可映射对象展开为位置参数或关键字参数在函数定义时,可变长位置和关键字参数用于收集多余的位置参数或关键字参数组成元组或字典对象deftracing(func,*args,**kwargs):

ifhasattr(func,'calls'):func.calls+=1

else:func.calls=1print(f'[{func.calls}]callingfunction:{func.__name__}(',end='')

ifargs:print(*args,sep=',',end=','ifkwargselse'')

ifkwargs:print(*(f'{k}={v}'fork,vinkwargs.items()),sep=',',end='')print(')')result=func(*args,**kwargs)print(f"{func.__name__}returned:{result}")

returnresultdefdemo(a,b=4,*x,**y):print(a,b,x,y)

if__name__=='__main__':tracing(demo,1)tracing(demo,1,2)tracing(demo,1,2,3,4,c=9,d=8)[1]callingfunction:demo(1)14(){}[2]callingfunction:demo(1,2)12(){}[3]callingfunction:demo(1,2,3,4,c=9,d=8)12(3,4){'c':9,'d':8}类型提示定义函数的时候不需要声明参数的类型,可以支持泛型Python3.5引入了类型提示,可以给变量、函数的参数和返回值增加注解,使得代码更加容易理解变量的类型提示:在变量名之后添加冒号和变量类型函数的类型提示:参数名之后添加冒号和参数类型提示函数头部结束的冒号之前添加->,后面给出函数的返回值类型defappend_left(v:list[int],n:int)->None:v.insert(0,n)

defreinit_key(d:dict[str,int],key:str)->None:

ifkeyind:d[key]=0name:str='Hello'

defsay_hi(name:str)->None:print(f'Hi{name}')

say_hi(123)#输出Hi123

defcubic(n:int|float)->int|float:

returnn**312.4名字空间名字空间名字空间是名字(变量)和对象的映射有哪些类型的名字空间?通过赋值类语句引入的名字属于哪个名字空间?赋值语句Import语句def语句参数传递for循环中的for变量表达式中出现未限定名时,该名字是哪个名字空间的名字?名字空间顶层名字空间:全局名字空间和内置名字空间全局名字空间也称为模块名字空间:不属于任何函数的函数体的赋值类语句引入的名字(全局变量)globals():返回字典对象,其key为名字,而value为对应的对象全局名字作用域为整个模块内置名字空间:解释器运行时其内部所加载的builtins模块的名字空间Importbuiltinsas__builtins__dir(__builtins__)本地名字空间:函数调用时创建的临时的名字空间,调用结束时释放函数体内赋值类语句引入的名字(本地或局部变量),作用域为(本次调用)当前函数体locals():返回当前名字空间。函数体内调用时返回本地名字空间允许函数嵌套:函数体内也可再定义一个新的函数内层函数的函数体内也可以访问外层(enclosing)函数名字空间的名字名字的作用域迟来绑定策略:只有在对表达式进行求解的时候,才会真正去相应的名字空间查找根据其所出现的位置,遵循LEGB(Local-Enclosing-Global-Builtin)的原则直到到达限定的名字空间范围,或找到匹配为止如果最终没有找到,则抛出异常NameError表达式出现在函数体外:顶层名字空间查找表达式出现在函数体内:是否有相关赋值类语句、global和nonlocal语句?赋值类语句:其先后顺序并不重要仅在本地名字空间查找global语句:顶层名字空间查找。通过赋值类语句更新时,更新的是全局名字空间的名字nonlocal语句:仅在外层名字空间查找,不会在顶层名字空间中查找否则按照顺序在Enclosing-Global-Builtin名字空间查找名字的作用域全局名字空间:random、update_all和s调用update_all,其本地名字空间:s,update,idx调用update时,其本地名字空间:idx自由变量:在某个函数的函数体内访问的位于更外层函数的名字空间的变量(名字)s为自由变量列表解析式类似于函数调用i为本地变量importrandomdefupdate_all(s):

defupdate(idx):s[idx]+=s[idx-1]

foridxinrange(1,len(s)):update(idx)s=[random.randint(0,10)foriinrange(10)]update_all(s)print(s)名字的作用域调用函数log1的本地名字空间:msg和msg_idmsg_id相关的赋值类语句导致msg_id仅仅在本地名字空间中查找logger='MAIN'msg_id=1deflog1(msg):print(f'[{logger}:{msg_id}]{msg}')msg_id+=1

#在交互式控制台执行>>>log1('firstmsg')Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>File"<stdin>",line2,inlog1UnboundLocalError:cannotaccesslocalvariable'msg_id'whereitis

notassociatedwithavalueglobal语句global语句:函数体内对于该名字通过赋值类语句更新时,更新的是全局名字空间的名字表达式中出现该名字时:顶层名字空间查找globals():返回全局名字空间的名字和对象的映射deflog2(msg):

globalmsg_idprint(f'[{logger}:{msg_id}]{msg}')msg_id+=1

#在交互式控制台执行>>>log2('firstmsg')[MAIN:1]firstmsg>>>log2('secondmsg')[MAIN:2]secondmsgdeflog3(msg):

importsysprint(f'[{logger}:{sys.modules[__name__].msg_id}]{msg}')globals()['msg_id']+=1

#在交互式控制台执行>>>log3('thirdmsg')[MAIN:3]thirdmsgnonlocal语句nonlocal语句限制不在当前函数的名字空间中查找,而是逐步外层(更外层)的函数名字空间中查找不会在顶层的名字空间中查找赋值类语句更改的也是外层的函数名字空间中的名字defmake_log(logger):msg_id=1

deflog(msg):

nonlocalmsg_idprint(f'[{logger}:{msg_id}]{msg}')msg_id+=1

returnlog#在交互式控制台执行>>>log4=make_log('LOGGER')>>>log4('firstmsg')[LOGGER:1]firstmsgnonlocal语句一个函数被称为闭包(closure)该函数体中有自由变量。函数定义嵌套,且访问了位于外层函数名字空间的名字自由变量对应的外层函数已经返回,该外层函数名字空间已经不再存在函数对象的属性__closure__中保存了自由变量与其对应的外层函数名字空间的名字之间的关联

>>>log4.__closure__(<cellat0x0000016374EF72B0:strobjectat0x0000016374F34D70>,<cellat0x0000016374F339A0:intobjectat0x00007FFF817FE348>)>>>log4.__closure__[0].cell_contents'LOGGER'>>>log4.__closure__[1].cell_contents212.5装饰器装饰器def语句定义函数func时,如果上一行出现@decorator,表示采用装饰器decorator对函数进行装饰,添加额外的功能等价于func=decorator(func)在被装饰的(原来真正要调用的)函数的基础上添加额外的功能defdecorator(func):

defwrapper(*args,**kwargs):print('calling%s'%func.__name__)

returnfunc(*args,**kwargs)

returnwrapper

@decoratordeffunc(x,y,z):

"""func'sdocstring"""print(x,y,z)importfunctoolsdefdecorator(func):@functools.wraps(func)

defwrapper(*args,**kwargs):print('calling%s'%func.__name__)

returnfunc(*args,**kwargs)

returnwrapper12.5lambda表达式lambda表达式以关键字lambda开始,接下来是参数部分,然后是冒号,最后是一个表达式创建一个匿名函数对象,避免了取名的烦恼,避免了可能的名字冲突参数定义、作用域规则、调用方式与def语句定义的函数完全等同defis_odd(x):

returnx%2

#上述函数的定义,可以通过赋值语句和lambda表达式实现is_odd=lambdax:x%2

importrandomdefscore():

returnrandom.randint(0,100)

#下面的语句等价score=lambda:random.randint(0,100)lambda表达式大部分情况下最后的表达式部分不用特别加上括号如果表达式为元组字面量定义时,建议不要省略圆括号deff(x=0):

returnx,x**2

#下面的语句等价f=lambdax=0:(x,x**2)12.7高阶函数map,filter和reducemap,filter也可使用生成器表达式实现函数功能map(func,iterable)等价于(func(item)foriteminiterable)filter(func,iterable)第1个参数为函数对象时,等价于(itemforiteminiterableiffunc(item))filter(None,iterable)第1个参数为None时,等价于(itemforiteminiterableifitem)

functools.reduce(func,iterable[,initial])将iterable中的元素根据func定义的规约方式归并在一起。如果传递第3个参数,表示在该参数的基础上规约s1=list(map(str,range(5)))#['0','1','2','3','4']s2=list(map(lambdax:2*x,range(10)))#[0,2,4,6,8,10,12,14,16,18]s3=1,2,'',0,-1,[]true_values=list(filter(None,s3))#[1,2,-1]even_numbers=list(filter(lambdax:x%2==0,range(10)))#[0,2,4,6,8]reducefunctools.reduce(func,iterable[,initial])func(current,element):之前规约结果与可迭代对象下一个元素如何规约fromfunctoolsimportreduce#采用lambda表达式定义加法规约函数sum_values=reduce(lambdax,y:x+y,range(10))#45

#首先将整数转换为字符串,然后利用加法运算将字符串合并concat_str=reduce(lambdax,y:x+y,map(str,range(10)))#'0123456789'

#抛出TypeError:reduce()ofemptyiterablewithnoinitialvaluereduce(lambdax,y:x+y,[])

reduce(lambdax,y:x+y,[],0)#0

deffactorial(n):

returnreduce(lambdax,y:x*y,range(1,n+1),1)sorted不通过key传递函数对象时,基于元素间的大小顺序,从小到大排列通过key传递函数对象:基于调用该函数之后的排序基准进行排列reverse:缺省的从小到大,还是从大到小排序排序算法是稳定的,即如果元素的排序基准相同时,按照该元素在原有可迭代对象出现的先后顺序进行排列listobj.sort(key=None,reverse=False)sorted(iterable,key=None,reverse=False)sorted>>>s=[30,26,26,15,11,1,12,4,27,11]>>>s[30,26,26,15,11,1,12,4,27,11]>>>sorted(s)[1,4,11,11,12,15,26,26,27,30]>>>defsum_digits(x):...returnsum(int(i)foriinstr(x))...>>>sorted(s,key=sum_digits)[1,11,11,30,12,4,15,26,26,27]>>>sorted(s,key=lambdax:sum(int(i)foriinstr(x)))[1,11,11,30,12,4,15,26,26,27]sorted新列表中的元素来自于可迭代对象如果传递的参数为元组、列表、集合等,则新列表中的元素就是这些对象中原来的元素。如果传递的参数为字典对象,新列表中的元素就是字典对象的key可迭代对象中的元素并没有任何限制,可以是任何类型的对象如果对象间无法比较大小,则需要通过key参数传递一个提供排序基准的函数对象排序的基准是什么?可以利用元素本身的大小关系有多个排序基准时,计算排序基准的函数对象返回一个包含(主排序基准,第2排序基准)的元组对象在多个排序基准中,如果升序和降序不同意某个排序基准是数值类型,则可以利用负数运算实现排序基准的统一sorted示例#单次销售信息为水果名称、价格和数量>>>sales=[['apple',6.0,5],['banana',2.30,10],['apple',5.50,10],['orange',4.50,5],['pearl',4.50,4.5],['banana',2.30,5],['pearl',5.50,10]]

#基于名称进行排序>>>sorted(sales)[['apple',5.5,10],['apple',6.0,5],['banana',2.3,5],['banana',2.3,10],['orange',4.5,5],['pearl',4.5,4.5],['pearl',5.5,10]]>>>sorted(sales,key=lambdaitem:item[0])[['apple',6.0,5],['apple',5.5,10],['banana',2.3,10],['banana',2.3,5],['orange',4.5,5],['pearl',4.5,4.5],['pearl',5.5,10]]

#基于价格进行排序,价格相同时,基于数量进行排序,数量相同时基于水果名>>>sorted(sales,key=lambdaitem:(item[1],item[2],item[0]))[['banana',2.3,5],['banana',2.3,10],['pearl',4.5,4.5],['orange',4.5,5],['apple',5.5,10],['pearl',5.5,10],['apple',6.0,5]]

#基于价格进行排序,价格相同时,基于数量进行排序,数量相同时基于水果名。数量要求采用降序,其余升序排列>>>sorted(sales,key=lambdaitem:(item[1],-item[2],item[0]))[['banana',2.3,10],['banana',2.3,5],['orange',4.5,5],['pearl',4.5,4.5],['apple',5.5,10],['pearl',5.5,10],['apple',6.0,5]]sorted示例:字典对象传递的可迭代对象为字典对象传递的可迭代对象为字典对象的items()返回的可迭代对象:(key,value)>>>inventory={'orange':45,'pear':58,'apple':125,'banana':45,'peach':15}

#基于水果名排序>>>[(fruit,inventory[fruit])forfruitinsorted(inventory)][('apple',125),('banana',45),('orange',45),('peach',15),('pear',58)]>>>sorted(inventory.items())[('apple',125),('banana',45),('orange',45),('peach',15),('pear',58)]

#基于数量排序,数量相同时基于水果名排序>>>[(fruit,inventory[fruit])forfruitinsorted(inventory,key=lambdafruit:(inventory[fruit],fruit))][('peach',15),('banana',45),('orange',45),('pear',58),('apple',125)]>>>sorted(inventory.items(),key=lambdaitem:(item[1],item[0]))[('peach',15),('banana',45),('orange',45),('pear',58),('apple',125)]sorted示例基于最高温度对城市名称进行排序,返回城市的名称的列表>>>cities=['Shanghai','Beijing','Wuhan','Chengdu','Nanjing']>>>temperatures=[30,26,34,29,38]>>>sorted(cities,key=lambdacity:temperatures[cities.index(city)])['Beijing','Chengdu','Shanghai','Wuhan','Nanjing']>>>[cityfortemp,cityinsorted(zip(temperatures,cities))]['Beijing','Chengdu','Shanghai','Wuhan','Nanjing']sortedfunctools.cmp_to_key(e1,e2):比较e1和e2,返回-1,0,1,对应e1<e2,e1==e2,e1>e2#姓名升序排列,姓名相同的时候,根据专业进行降序排列defmy_cmp_person(p1,p2):

ifp1[0]>p2[0]:

return1

elifp1[0]<p2[0]:

return-1

else:

ifp1[1]>p2[1]:

return-1

elifp1[1]<p2[1]:

return1

else:

return0records=[['tony','math',100],['tom','math',99],['bob','cs',98],['tony','cs',88],['tony','ee',87]]

k=sorted(records,key=functools.cmp_to_key(my_cmp_person))print(k)#[['bob','cs',98],['tom','math',99],['tony','math',100],['tony','ee',87],['tony','cs',88]]max,minmax(iterable,key=key)min(iterable,key=key)调用函数计算每个值的排序基准,返回排序基准最大或者最小所对应的值>>>s=[1,4,-5,-7,6]>>>max(s)6#序列解包展开为多个位置参数>>>min(*s)-7>>>max(s,key=abs)-7>>>min(*s,key=abs)1>>>words=['nice','to','console']>>>max(words,key=len)'console'生成器函数生成器表达式的一般化,给出了如何获取下一个元素的方法一个包含了yieldexpression的函数调用生成器函数时,传递参数之后暂停运行,返回一个迭代器对象,也称为生成器next(生成器器):等价于调用该生成器的__next__方法从上次暂停的地方恢复,继续执行执行到yield表达式时,暂停执行,将yield后面的表达式求解后的结果作为返回值返回给调用者继续执行到return语句,或者函数体后续没有更多的语句了,则抛出异常StopIteration生成器函数yieldfromexpression,相当于foriiniterable:yieldi。deff1():

yield

from'welcometothepythonworld.'

#函数f2等价于上面的函数f1deff2():

foriin'welcometothepythonworld.':

yieldi

print(list(f2()))生成器函数deffind_all_solutions():solutions=[]

whileTrue:solution=find_next_solution()

if

notsolution:

breaksolutions.append(solution)returnsolutionsdefall_solutions_iterator():

whileTrue:solution=find_next_solution()

if

notsolution:

break

yieldsolution

forsolutioninall_solutions_iterator():print(solution)生成器函数defcount(start=0,step=1):

whileTrue:

yieldstartstart+=step

#for循环,i从0开始递增到永远,输出100以内那些10的倍数

foriincount():

ifi%10==0:print(i)

ifi>100:

break生成器函数deffib(n):prev,curr=1,1

whileprev<n:print(prev,end='')prev,curr=curr,prev+currprint()deffib_iterator():prev,curr=1,1

whileTrue:

yieldprevprev,curr=curr,prev+curr

#返回前10个数:11235813213455fibs=fib_iterator()first_10_fibs=[next(fibs)foriinrange(10)]print('前面10个斐波那契数:',*first_10_fibs)

#返回1000以内的fibonacci数count=0foriinfib_iterator():

ifi>1000:

breakprint(i,end='\t')count+=1

ifcount%5==0:print()12.8递归函数递归函数函数体内部直接或者间接调用自身的函数某个复杂的问题可进一步分解,在一个与原问题相似、但是规模更小的问题的基础上进行求解确定递归关系:将递归函数看成一个黑盒子,写出递归调用的代码确定问题的基本情形:写出递归结束条件递归调用的次数不可超过系统允许的递归深度defsolve(problem):

ifproblem为基本情形:

对该问题进行求解

else:

将问题分解为规模更小的子问题

通过递归求解这些子问题

根据子问题的解给出当前问题的解deffactorial(n):

if

noti

温馨提示

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

最新文档

评论

0/150

提交评论