版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第7章函數(shù)定義與使用董付國微信公眾號:Python小屋本章學習目標理解函數(shù)與代碼復(fù)用的關(guān)系熟練掌握函數(shù)定義與調(diào)用的語法理解遞歸函數(shù)的語法和執(zhí)行過程理解嵌套定義函數(shù)的語法和執(zhí)行過程理解位置參數(shù)、默認值參數(shù)、關(guān)鍵參數(shù)和可變長度參數(shù)的原理并能夠熟練使用理解實參序列解包的語法理解變量作用域的概念熟練掌握lambda表達式語法與應(yīng)用理解生成器函數(shù)的工作原理7.1函數(shù)定義與調(diào)用函數(shù)是代碼復(fù)用的重要實現(xiàn)方式之一。把用來解決某一類問題的功能代碼封裝成函數(shù),可以重復(fù)利用這些功能,使得代碼更簡潔,也更容易維護。除了內(nèi)置函數(shù)、標準庫函數(shù)和擴展庫函數(shù),Python還允許用戶自定義函數(shù)。7.1.1基本語法在Python中,使用關(guān)鍵字def定義具名函數(shù),使用lambda表達式定義匿名函數(shù)。具名函數(shù)定義語法形式如下:def函數(shù)名([形參列表]):'''文檔字符串'''函數(shù)體7.1.1基本語法定義函數(shù)時需要注意的問題主要有:1)函數(shù)名和形參名建議使用“見名知義”的英文單詞或單詞組合;2)不需要說明形參類型,調(diào)用函數(shù)時Python解釋器會根據(jù)實參的值自動推斷和確定形參類型;3)不需要指定函數(shù)返回值類型,這由函數(shù)中return語句返回的值來確定;4)上面的語法中方括號表示其中的參數(shù)列表可有可無,即使該函數(shù)不需要接收任何參數(shù),也必須保留一對空的圓括號,如果需要接收多個形式參數(shù)應(yīng)使用逗號分隔;5)函數(shù)頭部括號后面的冒號必不可少;6)函數(shù)體相對于def關(guān)鍵字必須保持一定的空格縮進,函數(shù)體內(nèi)部的代碼縮進與前面章節(jié)學過的選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、異常處理結(jié)構(gòu)以及with語句具有相同的要求;7)函數(shù)體前面三引號和里面的文檔字符串可以不寫,但最好寫上,用簡短語言描述函數(shù)功能、參數(shù)和返回值,使得接口更加友好;8)在函數(shù)體中使用return語句指定返回值,如果函數(shù)沒有return語句、有return語句但是沒有執(zhí)行到或者有return也執(zhí)行到了但是沒有返回任何值,Python都認為返回的是空值None。7.1.1基本語法Python也允許自定義函數(shù)中說明參數(shù)類型和返回值類型,但僅僅是說明而已,并不真正起作用,不屬于強約束。例如,下面的代碼中雖然指定參數(shù)a和b以及函數(shù)返回值都為整數(shù),但實際上并不會有任何限制。deffunc(a:int,b:int)->int:returna+bprint(func(3,5))print(func(3.14,9.8))print(func('Python','小屋'))print(func([3],[4]))運行結(jié)果為:812.940000000000001Python小屋[3,4]7.1.1基本語法例7-1編寫函數(shù),接收一個大于0的整數(shù)或?qū)崝?shù)r表示圓的半徑,返回一個包含圓的周長與面積的元組,小數(shù)位數(shù)最多保留3位。然后編寫程序,調(diào)用剛剛定義的函數(shù)。frommathimportpidefget_area(r):'''接收圓的半徑為參數(shù),返回包含周長和面積的元組'''return(round(2*pi*r,3),round(pi*r*r,3))r=input('請輸入圓的半徑:')try:r=float(r)assertr>0except:print('必須輸入大于0的整數(shù)或?qū)崝?shù)')else:print(get_area(r))運行結(jié)果為:請輸入圓的半徑:6(37.699,113.097)7.1.2遞歸函數(shù)定義與調(diào)用如果一個函數(shù)在執(zhí)行過程中特定條件下又調(diào)用了這個函數(shù)自己,叫作遞歸調(diào)用。遞歸函數(shù)用來把一個大型的復(fù)雜問題層層轉(zhuǎn)化為一個與原來問題本質(zhì)相同但規(guī)模更小、更容易解決或描述的問題,只需要很少的代碼就可以描述解決問題過程中需要的大量重復(fù)計算。在編寫遞歸函數(shù)時,應(yīng)注意以下幾點:1)每次遞歸應(yīng)保持問題性質(zhì)不變;2)每次遞歸應(yīng)使得問題規(guī)模變小或使用更簡單的輸入;3)必須有一個能夠直接處理而不需要再次進行遞歸的特殊情況來保證遞歸過程可以結(jié)束;4)函數(shù)遞歸深度不能太大,否則會引起內(nèi)存崩潰。7.1.2遞歸函數(shù)定義與調(diào)用例7-2已知正整數(shù)的階乘計算公式為n!=n×(n-1)×(n-2)×...×3×2×1,并且已知1的階乘為1,也就是1!=1。編寫遞歸函數(shù),接收一個正整數(shù)n,計算并返回n的階乘。deffac(n):#1的階乘為1,這是保證遞歸可以結(jié)束的條件ifn==1:#如果執(zhí)行到這個return語句,函數(shù)直接結(jié)束,不會再執(zhí)行后面的代碼return1#遞歸調(diào)用函數(shù)自己,使用越來越小的輸入,使得遞歸過程可以結(jié)束returnn*fac(n-1)#調(diào)用函數(shù),計算并輸出5的階乘print(fac(5))運行結(jié)果為:1207.2函數(shù)參數(shù)函數(shù)定義時圓括號內(nèi)是使用逗號分隔開的形參列表,函數(shù)可以有多個參數(shù),也可以沒有參數(shù)。調(diào)用函數(shù)時將實參的引用傳遞給形參,在進入被調(diào)函數(shù)內(nèi)部的瞬間,形參和實參引用的是同一個對象。在函數(shù)內(nèi)部,形參相當于局部變量。由于Python中變量存儲的是值的引用,直接修改形參的值實際上是修改了形參變量的引用,不會影響實參。7.2函數(shù)參數(shù)defdemo(num):#剛剛進入函數(shù)時,形參與實參引用相同的對象result=num#內(nèi)置函數(shù)id()用來查看對象的內(nèi)存地址,不用過多關(guān)心#這里重點關(guān)心的是變量result、num的內(nèi)存地址與函數(shù)外的變量num相同print(id(num),id(result))whilenum>1:#每次執(zhí)行都會修改變量num和result的引用#此后num就和原來的實參再也沒有關(guān)系了num=num-1result=result*numreturnresultnum=5print(num,id(num))#調(diào)用函數(shù),傳遞實參print(demo(num))#原來的實參變量沒有受任何影響,內(nèi)存地址不變print(num,id(num))運行結(jié)果為:514072660741916814072660741916814072660741916812051407266074191687.2函數(shù)參數(shù)如果調(diào)用函數(shù)時傳遞的實參是列表、字典、集合這樣的可變對象,函數(shù)內(nèi)部的代碼是否會影響實參的值要分兩種情況:1)如果在函數(shù)內(nèi)部像上面的代碼一樣直接修改形參的引用,不會影響實參;2)如果在函數(shù)內(nèi)部使用下標的形式或者調(diào)用對象自身提供的原地操作方法,例如列表的append()、insert()、pop()等方法,或者集合的add()、discard()等方法,會影響實參。7.2函數(shù)參數(shù)defdemo(test_list,test_dict,test_set):#在列表尾部追加元素test_list.append(666)#在列表開始位置插入元素test_list.insert(0,666)#如果字典中有“鍵”為'name'的元素就修改對應(yīng)的“值”,否則插入新元素test_dict['name']='xiaoming'#如果集合中沒有元素666就放進去,如果已經(jīng)存在就忽略test_set.add(666)data_list=[1,2,3]data_dict={'name':'xiaohong','age':23}data_set={1,2,3}demo(data_list,data_dict,data_set)print(data_list,data_dict,data_set,sep='\n')運行結(jié)果為:[666,1,2,3,666]{'name':'xiaoming','age':23}{1,2,3,666}7.2.1位置參數(shù)位置參數(shù)是指調(diào)用函數(shù)時實參沒有任何說明,直接放在括號內(nèi)調(diào)用函數(shù),按位置和順序傳遞實參,第一個實參傳遞給第一個形參,第二個實參傳遞給第二個形參,以此類推。實參和形參的順序必須嚴格一致,并且實參和形參的數(shù)量必須相同,否則會導(dǎo)致邏輯錯誤得到不正確結(jié)果或者拋出TypeError異常并提示參數(shù)數(shù)量不對。deffunc(a,b,c):returnsum((a,b,c))print(func(1,2,3))print(func(4,5,6))運行結(jié)果為:6157.2.1位置參數(shù)在Python3.8以及更新的版本中,允許在定義函數(shù)時設(shè)置一個斜線“/”作為參數(shù),斜線“/”本身并不是真正的參數(shù),僅用來說明該位置之前的所有參數(shù)必須以位置參數(shù)的形式進行傳遞。>>>deffunc(a,b,c,/):returnsum((a,b,c))>>>func(3,5,7)#所有參數(shù)都按位置傳遞15>>>func(3,5,c=7)#參數(shù)c沒有使用位置參數(shù)的形式,代碼出錯TypeError:func()gotsomepositional-onlyargumentspassedaskeywordarguments:'c'7.2.2默認值參數(shù)在定義函數(shù)時可以為形參設(shè)置默認值,調(diào)用這樣的函數(shù)時,可以不用為設(shè)置了默認值的形參進行傳遞實參,此時函數(shù)將會直接使用函數(shù)定義時設(shè)置的默認值。也可以顯式為帶默認值的形參傳遞實參,本次調(diào)用中不再使用形參的默認值。在定義帶有默認值參數(shù)的函數(shù)時,任何一個默認值參數(shù)右邊都不能再出現(xiàn)沒有默認值的普通位置參數(shù),否則會拋出SyntaxError異常并提示“non-defaultargumentfollowsdefaultargument”。帶有默認值參數(shù)的函數(shù)定義語法如下:def函數(shù)名(……,形參名=默認值):函數(shù)體7.2.2默認值參數(shù)deffunc(message,times=3):returnmessage*timesprint(func('重要的事情說三遍!'))print(func('不重要的事情只說一遍!',1))print(func('特別重要的事情說五遍!',5))運行結(jié)果為:重要的事情說三遍!重要的事情說三遍!重要的事情說三遍!不重要的事情只說一遍!特別重要的事情說五遍!特別重要的事情說五遍!特別重要的事情說五遍!特別重要的事情說五遍!特別重要的事情說五遍!7.2.2默認值參數(shù)如果定義函數(shù)時需要為部分變量設(shè)置默認值,一定要注意盡量使用整數(shù)、實數(shù)、復(fù)數(shù)、元組、字符串、空值None或True/False這樣的不可變對象,要避免使用列表、字典、集合這樣的可變對象作為參數(shù)的默認值,除非有特殊需要。函數(shù)參數(shù)默認值是在定義函數(shù)時創(chuàng)建的對象,并且把默認值的引用保存在函數(shù)的特殊成員“__defaults__”中,這是一個元組,里面保存了函數(shù)每個參數(shù)默認值的引用,每次調(diào)用函數(shù)且不為帶默認值的參數(shù)傳遞實參時,都會使用特殊成員“__defaults__”里保存的引用。如果參數(shù)默認值是可變對象并且在函數(shù)內(nèi)部有使用下標或?qū)ο笞陨淼脑夭僮鞣椒▽?shù)進行操作的語句,會影響后續(xù)調(diào)用。7.2.3關(guān)鍵參數(shù)關(guān)鍵參數(shù)是指調(diào)用函數(shù)時按參數(shù)名字進行傳遞的形式,明確指定哪個實參傳遞給哪個形參。通過這樣的調(diào)用方式,實參順序可以和形參順序不一致,但不影響參數(shù)的傳遞結(jié)果,避免了用戶需要牢記參數(shù)位置和順序的麻煩,使得函數(shù)的調(diào)用和參數(shù)傳遞更加靈活方便。7.2.3關(guān)鍵參數(shù)deffunc(a,b,c):returnf'{a=},{b=},{c=}'print(func(a=3,c=5,b=8))print(func(c=5,a=3,b=8))運行結(jié)果為:a=3,b=8,c=5a=3,b=8,c=57.2.3關(guān)鍵參數(shù)在Python3.8以及更新的版本中,允許在自定義函數(shù)中使用單個星號“*”作為參數(shù),但單個星號并不是真正的參數(shù),僅用來說明該位置后面的所有參數(shù)必須以關(guān)鍵參數(shù)的形式進行傳遞。>>>deffunc(a,*,b,c):returnf'{a=},{b=},{c=}'>>>print(func(3,5,8))#實參傳遞方式不對,代碼出錯TypeError:func()takes1positionalargumentbut3weregiven>>>print(func(3,b=5,c=8))a=3,b=5,c=8>>>print(func(3,c=5,b=8))a=3,b=8,c=5#關(guān)鍵參數(shù)的參數(shù)名必須是在函數(shù)定義中存在的或者可以接收的,否則出錯>>>print(func(3,b=4,c=5,d=6))TypeError:func()gotanunexpectedkeywordargument'd'7.2.3關(guān)鍵參數(shù)在Python3.8以上的版本中,可以同時使用單個斜線和星號作參數(shù)來明確要求其他參數(shù)的傳遞形式。>>>deffunc(a,/,*,b,c):returnf'{a=},{b=},{c=}'>>>print(func(3,b=5,c=8))a=3,b=5,c=8>>>print(func(a=3,b=5,c=8))#參數(shù)a不能使用關(guān)鍵參數(shù)傳遞TypeError:func()gotsomepositional-onlyargumentspassedaskeywordarguments:'a'>>>print(func(3,5,8))#參數(shù)b和c不能使用位置參數(shù)傳遞TypeError:func()takes1positionalargumentbut3weregiven7.2.4可變長度參數(shù)可變長度參數(shù)是指形參對應(yīng)的實參數(shù)量不確定,一個形參可以接收多個實參。在定義函數(shù)時主要有兩種形式的可變長度參數(shù):*parameter和**parameter,前者用來接收任意多個位置實參并將其放在一個元組中,后者接收任意多個關(guān)鍵參數(shù)并將其放入字典中。7.2.4可變長度參數(shù)defdemo(a,b,c,*p):#參數(shù)p是個元組print(a,b,c)print(p)demo(1,2,3,4,5,6)print('='*10)demo(1,2,3,4,5,6,7,8)運行結(jié)果為:123(4,5,6)==========123(4,5,6,7,8)7.2.4可變長度參數(shù)defdemo(**p):#參數(shù)p是個字典foriteminp.items():print(item)demo(x=1,y=2,z=3)print('='*10)demo(a=4,b=5,c=6,d=7)運行結(jié)果為:('x',1)('y',2)('z',3)==========('a',4)('b',5)('c',6)('d',7)7.2.5實參解包調(diào)用函數(shù)時可以對實參可迭代對象進行解包,將其中的元素作為參數(shù)傳遞給形參。在調(diào)用函數(shù)并且使用可迭代對象作為實參時,在實參可迭代對象前面加一個星號表示把其中的元素轉(zhuǎn)換為普通的位置參數(shù);在實參字典前面加一個星號表示把字典中的“鍵”轉(zhuǎn)換為普通的位置參數(shù);在字典前加兩個星號表示把其中的所有元素都轉(zhuǎn)換為關(guān)鍵參數(shù),元素的“鍵”作為實參的名字,元素的“值”作為實參的值。deffunc(a,b,c):print(f'{a=},{b=},{c=}')func(*[3,5,7])func(**{'a':97,'b':98,'c':99})運行結(jié)果為:a=3,b=5,c=7a=97,b=98,c=997.3變量作用域變量起作用的代碼范圍稱為變量的作用域,不同作用域內(nèi)變量名字可以相同,互不影響。從搜索順序來看,由近及遠有局部變量、nonlocal變量、全局變量和內(nèi)置對象。Python解釋器在訪問變量時,會按照這個順序進行搜索并使用遇到的第一個同名變量,如果搜索過程結(jié)束仍沒有找到,引發(fā)異常并提示變量沒有定義。如果在函數(shù)內(nèi)只有引用某個變量值的操作而沒有為其賦值的操作,該變量默認為全局變量、外層函數(shù)的變量或者內(nèi)置命名空間中的成員,如果都不是則會拋出異常并提示沒有定義。如果在函數(shù)內(nèi)有為變量賦值的操作,該變量就被認為是局部變量,除非在函數(shù)內(nèi)賦值操作之前用關(guān)鍵字global或nonlocal進行了聲明。7.3變量作用域在Python中有兩種創(chuàng)建全局變量的方式:1)在函數(shù)外部使用賦值語句創(chuàng)建的變量默認為全局變量,其作用域為從定義的位置開始一直到文件結(jié)束;2)在函數(shù)內(nèi)部使用關(guān)鍵字global聲明變量為全局變量,其作用域從調(diào)用該函數(shù)的語句開始一直到文件結(jié)束。Python關(guān)鍵字global有兩個作用:1)對于在函數(shù)外創(chuàng)建的全局變量,如果需要在函數(shù)內(nèi)修改這個變量的值,并要將這個結(jié)果反映到函數(shù)外,可以在函數(shù)內(nèi)使用關(guān)鍵字global聲明要使用這個全局變量。2)如果一個變量在函數(shù)外沒有定義,在函數(shù)內(nèi)部也可以直接將一個變量聲明為全局變量,該函數(shù)執(zhí)行后,將增加一個新的全局變量。7.3變量作用域defdemo():globalx#聲明或創(chuàng)建全局變量,必須在使用變量x之前執(zhí)行該語句x=3#修改全局變量的值y=4#局部變量print(x,y)
#使用變量x和y的值x=5#在函數(shù)外部定義了全局變量xdemo()#本次調(diào)用修改了全局變量x的值print(x)try:print(y)except:print('不存在變量y')delx#刪除全局變量xtry:print(x)except:print('不存在變量x')demo()#本次調(diào)用創(chuàng)建了全局變量print(x)運行結(jié)果為:343不存在變量y不存在變量x3437.3變量作用域除了局部變量和全局變量,Python還支持使用nonlocal關(guān)鍵字定義一種介于二者之間的變量。關(guān)鍵字nonlocal聲明的變量一般用于嵌套函數(shù)定義的場合(例如,在嵌套函數(shù)定義的場合中,內(nèi)層函數(shù)可以把外層函數(shù)中的變量聲明為nonlocal變量),要求聲明的變量已經(jīng)存在,關(guān)鍵字nonlocal不會創(chuàng)建新變量。7.3變量作用域defscope_test():defdo_local():spam="我是局部變量"defdo_nonlocal():nonlocalspam#要求spam必須是外層函數(shù)中定義的變量spam="我不是局部變量,也不是全局變量"defdo_global():globalspam#如果全局作用域內(nèi)沒有spam,自動新建spam="我是全局變量"spam="原來的值"do_local()print("局部變量賦值后:",spam)do_nonlocal()print("nonlocal變量賦值后:",spam)do_global()print("全局變量賦值后:",spam)scope_test()print("全局變量:",spam)運行結(jié)果為:局部變量賦值后:原來的值nonlocal變量賦值后:我不是局部變量,也不是全局變量全局變量賦值后:我不是局部變量,也不是全局變量全局變量:我是全局變量7.4lambda表達式語法與應(yīng)用lambda表達式常用來聲明匿名函數(shù),也就是沒有名字的、臨時使用的小函數(shù),雖然也可以使用lambda表達式定義具名函數(shù),但很少這樣使用。lambda表達式只能包含一個表達式,表達式的計算結(jié)果相當于函數(shù)的返回值。lambda表達式的語法如下:lambda[形參列表]:表達式lambda表達式屬于Python可調(diào)用對象類型之一,下面代碼中的函數(shù)func和lambda表達式func在功能上是完全等價的。deffunc(a,b,c):returnsum((a,b,c))func=lambdaa,b,c:sum((a,b,c))7.4lambda表達式語法與應(yīng)用lambda表達式常用在臨時需要一個函數(shù)的功能但又不想定義函數(shù)的場合,例如內(nèi)置函數(shù)sorted(iterable,/,*,key=None,reverse=False)、max(iterable,*[,default=obj,key=func])、min(iterable,*[,default=obj,key=func])和列表方法sort(*,key=None,reverse=False)的key參數(shù),內(nèi)置函數(shù)map(func,*iterables)、filter(functionorNone,iterable)以及標準庫函數(shù)functools.reduce(function,sequence[,initial])的第一個參數(shù)。7.4lambda表達式語法與應(yīng)用fromfunctoolsimportreducefromrandomimportsample,seedseed(202208151630)#生成隨機數(shù)據(jù),包含5個子列表,每個子列表中包含10個整數(shù)#每個整數(shù)介于[0,20)區(qū)間,同一個子列表中的整數(shù)不重復(fù)data=[sample(range(20),10)foriinrange(5)]#按子列表的原始順序輸出,每個子列表占一行print(*data,sep='\n',end='\n===\n')#按子列表從小到大順序輸出,每個子列表占一行print(*sorted(data),sep='\n',end='\n===\n')#按每個子列表中第2個元素升序輸出print(*sorted(data,key=lambdarow:row[1]),sep='\n',end='\n===\n')#按每個子列表第2個元素升序輸出,如果第2個元素相等再按第4個升序輸出print(*sorted(data,key=lambdarow:(row[1],row[3])),sep='\n',end='\n===\n')7.4lambda表達式語法與應(yīng)用#第一個子列表中所有元素連乘的結(jié)果print(reduce(lambdax,y:x*y,data[0]),end='\n===\n')#第二個子列表中所有元素連乘的結(jié)果print(reduce(lambdax,y:x*y,data[1]),end='\n===\n')#每個子列表的第一個元素組成的新列表print(list(map(lambdarow:row[0],data)),end='\n===\n')#對角線元素組成的列表print(list(map(lambdarow:row[data.index(row)],data)),end='\n===\n')#最后一個元素最大的子列表print(max(data,key=lambdarow:row[-1]),end='\n===\n')#所有元素之和為偶數(shù)的子列表print(*filter(lambdarow:sum(row)%2==0,data),sep='\n',end='\n===\n')#所有元素之和小于等于80的子列表print(*filter(lambdarow:sum(row)<=80,data),sep='\n',end='\n===\n')#每列元素之和組成的新列表print(reduce(lambdax,y:list(map(lambdai,j:i+j,x,y)),data))7.5生成器函數(shù)定義與使用如果函數(shù)中包含yield語句,那么調(diào)用這個函數(shù)得到的返回值不是單個簡單值,而是一個可以生成若干值的生成器對象,這樣的函數(shù)也稱生成器函數(shù)。生成器對象屬于迭代器對象之一,當通過內(nèi)置函數(shù)next()、for循環(huán)遍歷生成器對象或其他方式(例如使用list()轉(zhuǎn)換成列表、使用tuple()轉(zhuǎn)換為元組)顯式“索要”數(shù)據(jù)時,生成器函數(shù)中的代碼開始執(zhí)行,執(zhí)行到y(tǒng)ield語句時,生成并提供一個值,然后暫停執(zhí)行,下次再“索要”數(shù)據(jù)時恢復(fù)執(zhí)行,不停地暫停與恢復(fù),直到用完所有數(shù)據(jù)為止。7.5生成器函數(shù)定義與使用deffib():a,b=1,1#序列解包,同時為多個對象賦值whileTrue:yielda#產(chǎn)生一個值,然后暫停執(zhí)行a,b=b,a+b#序列解包,修改對象的值gen=fib()#創(chuàng)建生成器對象foriinrange(10):
#斐波那契數(shù)列中前10個數(shù)字print(next(gen),end='')
#使用內(nèi)置函數(shù)next()獲取下一個值print()foriinfib():#創(chuàng)建生成器對象并使用for循環(huán)遍歷所有的數(shù)字ifi>100:#元素大于100時結(jié)束循環(huán)print(i,end='')breakprint()7.5生成器函數(shù)定義與使用deffunc():yieldfrom'abcdefg'#使用yieldfrom語句實現(xiàn)前面代碼中循環(huán)結(jié)構(gòu)的功能gen=func()print(next(gen))#使用內(nèi)置函數(shù)next()獲取下一個值print(next(gen))foritemingen:#遍歷剩余的所有的值print(item)defgen():yield1yield2yield3x,y,z=gen()#生成器對象支持序列解包print(x,y,z)print(*gen())#這也是序列解包的用法7.5生成器函數(shù)定義與使用例7-3編寫生成器函數(shù),模擬標準庫itertools中cycle()函數(shù)的工作原理。defmyCycle(iterable):iterable=tuple(iterable)whileTrue:foriteminiterable:yielditemc=myCycle(map(str,range(3)))foriinrange(20):print(next(c),end=',')print()c=myCycle(map(chr,range(65,69)))foriinrange(20):print(next(c),end=',')運行結(jié)果為:0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,A,B,C,D,A,B,C,D,A,B,C,D,A,B,C,D,A,B,C,D,7.7綜合例題解析例7-4編寫遞歸函數(shù),判斷給定的字符串text是否為回文,也就是從前向后讀和從后向前讀都一樣的字符串。判斷回文有很多種方法,在Python中最簡單的應(yīng)該是檢查表達式text==text[::-1]的值是否為True。如果使用遞歸的話思路是這樣的,先檢查字符串首尾字符是否一樣,如果不一樣就直接判斷不是回文;如果首尾字符一樣,那么原字符串是否為回文取決于去除首尾字符后得到的新字符串是否為回文。7.7綜合例題解析defcheck(text):#遞歸結(jié)束條件,長度為0或1的字符串是回文iflen(text)in(0,1):returnTrue#遞歸結(jié)束條件,首尾字符不相等的字符串不是回文iftext[0]!=text[-1]:returnFalsereturncheck(text[1:-1])texts=('eye','rotator','madam','level','indeed',
'sky','python','畫中畫','天外天','拜拜','您吃了嗎','上海自來水來自海上','霧鎖山頭山鎖霧')fortextintexts:print(f'{text}:{check(text)}')運行結(jié)果為:eye:Truerotator:Truemadam:Truelevel:Trueindeed:Falsesky:Falsepython:False畫中畫:True天外天:True拜拜:True您吃了嗎:False上海自來水來自海上:True霧鎖山頭山鎖霧:True7.7綜合例題解析例7-5編寫函數(shù),模擬猜數(shù)游戲。系統(tǒng)隨機在參數(shù)指定的范圍內(nèi)產(chǎn)生一個數(shù),玩家最大猜測次數(shù)也由參數(shù)指定,每次猜測之后系統(tǒng)會根據(jù)玩家的猜測進行提示,玩家則可以根據(jù)系統(tǒng)的提示對下一次的猜測進行適當調(diào)整,直到猜對或者次數(shù)用完。7.7綜合例題解析fromrandomimportrandintdefguess(start,stop,maxTimes):#隨機生成一個整數(shù)value=randint(start,stop)foriinrange(maxTimes):prompt='開始猜吧:'ifi==0else'再猜一次:'try:#防止輸入不是整數(shù)的情況x=int(input(prompt))except:print('必須輸入整數(shù)')else:ifx==value:print('恭喜,猜對了!')breakelifx>value:print('太大了。')else:print('太小了。')else:print('次數(shù)用完了,游戲結(jié)束。')print('正確的數(shù)字是:',value)guess(100,110,3)7.7綜合例題解析例7-6編寫函數(shù),計算形式如a+aa+aaa+aaaa+...+aaa...aaa的表達式前n項的值,其中a為小于10的自然數(shù)。defdemo(a,n):asserttype(a)==intand0<a<10,'參數(shù)a必須介于[1,9]區(qū)間'assertisinstance(n,int)andn>0,'參數(shù)n必須為正整數(shù)'result,t=0,0foriinrange(n):t=t*10+aresult=result+treturnresultprint(demo(1,9))print(demo(6,8))運行結(jié)果為:123456789740740687.7綜合例題解析例7-7假設(shè)一段樓梯共15個臺階,小明一步最多能上3個臺階,編寫程序計算小明上這段樓梯一共有多少種方法。defclimb_stairs(n):a,b,c=1,2,4foriinrange(n-3):c,b,a=a+b+c,c,breturncprint(climb_stairs(15))運行結(jié)果為:57687.7綜合例題解析例7-8
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024版文具采購合同3篇
- 專用木結(jié)構(gòu)工程承包合同書2024年版版B版
- 專業(yè)橋架施工包工協(xié)議范例(2024版)版B版
- 2025年4S店汽車銷售及二手車置換服務(wù)合同范本3篇
- 2024跨國技術(shù)轉(zhuǎn)讓與合作合同
- 專業(yè)項目建議書編寫委托協(xié)議簡化版版B版
- 2025年度科研場地租賃合同終止及設(shè)備回收協(xié)議3篇
- 2025年度老舊小區(qū)墻體拆除及改造工程勞務(wù)分包合同范本4篇
- 2025年度酒店會議室租賃協(xié)議書(含全方位服務(wù)套餐)
- 二零二五年度食堂食堂食堂食堂員工餐廳食品安全監(jiān)管合同
- 金色簡約蛇年年終總結(jié)匯報模板
- 農(nóng)用地土壤環(huán)境質(zhì)量類別劃分技術(shù)指南(試行)(環(huán)辦土壤2017第97號)
- 反向開票政策解讀課件
- 工程周工作計劃
- 房地產(chǎn)銷售任務(wù)及激勵制度
- 六年級語文下冊14文言文二則《學弈》課件
- 2024年內(nèi)蒙古中考語文試卷五套合卷附答案
- 并購指南(如何發(fā)現(xiàn)好公司)
- 垃圾分類亭合同協(xié)議書
- 物權(quán)轉(zhuǎn)移協(xié)議
- 高三高考地理一輪課時練習:洋流(單選題)
評論
0/150
提交評論