Python編程從入門到實(shí)戰(zhàn)-輕松過二級(jí) (思政版)(第2版) 課件 Ch04 函數(shù)和代碼復(fù)用_第1頁(yè)
Python編程從入門到實(shí)戰(zhàn)-輕松過二級(jí) (思政版)(第2版) 課件 Ch04 函數(shù)和代碼復(fù)用_第2頁(yè)
Python編程從入門到實(shí)戰(zhàn)-輕松過二級(jí) (思政版)(第2版) 課件 Ch04 函數(shù)和代碼復(fù)用_第3頁(yè)
Python編程從入門到實(shí)戰(zhàn)-輕松過二級(jí) (思政版)(第2版) 課件 Ch04 函數(shù)和代碼復(fù)用_第4頁(yè)
Python編程從入門到實(shí)戰(zhàn)-輕松過二級(jí) (思政版)(第2版) 課件 Ch04 函數(shù)和代碼復(fù)用_第5頁(yè)
已閱讀5頁(yè),還剩44頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第二版本章要點(diǎn):4.1函數(shù)概述4.2函數(shù)的聲明和調(diào)用4.3參數(shù)的傳遞4.4函數(shù)的返回值4.5變量的作用域4.6遞歸函數(shù)4.7內(nèi)置函數(shù)的使用4.8綜合應(yīng)用:turtle模塊繪制復(fù)雜的圖形第4章函數(shù)和代碼復(fù)用4.1函數(shù)概述函數(shù)的功能(1)實(shí)現(xiàn)結(jié)構(gòu)化程序設(shè)計(jì)。通過把程序分割為不同的功能模塊,可以實(shí)現(xiàn)自頂向下的結(jié)構(gòu)化設(shè)計(jì)(2)減少程序的復(fù)雜度。簡(jiǎn)化程序的結(jié)構(gòu),提高程序的可閱讀性(3)實(shí)現(xiàn)代碼的復(fù)用。一次定義多次調(diào)用,實(shí)現(xiàn)代碼的可重用性(4)提高代碼的質(zhì)量。實(shí)現(xiàn)分割后子任務(wù)的代碼相對(duì)簡(jiǎn)單,易于開發(fā)、調(diào)試、修改和維護(hù)(5)協(xié)作開發(fā)。大型項(xiàng)目分割成不同的子任務(wù)后,團(tuán)隊(duì)多人可以分工合作,同時(shí)進(jìn)行協(xié)作開發(fā)(6)實(shí)現(xiàn)特殊功能。遞歸函數(shù)可以實(shí)現(xiàn)許多復(fù)雜的算法函數(shù)的基本概念函數(shù)用于在程序中分離不同的任務(wù)函數(shù)允許程序的控制在調(diào)用代碼和函數(shù)代碼之間切換Python函數(shù)分類內(nèi)置函數(shù)。Python語(yǔ)言內(nèi)置了若干常用的函數(shù),例如abs()、len()等等,在程序中可以直接使用標(biāo)準(zhǔn)庫(kù)函數(shù)。Python語(yǔ)言安裝程序同時(shí)會(huì)安裝若干標(biāo)準(zhǔn)庫(kù),例如math、random等等。通過import語(yǔ)句,可以導(dǎo)入標(biāo)準(zhǔn)庫(kù),然后使用其中定義的函數(shù)第三方庫(kù)函數(shù)。Python社區(qū)提供了許多其他高質(zhì)量的庫(kù),如Python圖像庫(kù)等等。下載安裝這些庫(kù)后,通過import語(yǔ)句,可以導(dǎo)入庫(kù),然后使用其中定義的函數(shù)用戶自定義函數(shù)。本章將詳細(xì)討論函數(shù)的定義和調(diào)用方法010302044.2函數(shù)的聲明和調(diào)用(1)defmy_average(a,b):

return(a+b)/2defprint_star(n):print(("*"*n).center(50))

#打印n個(gè)星號(hào),兩邊填充#空格,總寬度50【例4.2】函數(shù)創(chuàng)建示例2:定義打印n個(gè)星號(hào)的無返回值的函數(shù)【例4.1】函數(shù)創(chuàng)建示例1:定義返回兩個(gè)數(shù)平均值的函數(shù)def·函數(shù)名([形參列表]):····函數(shù)體函數(shù)的聲明和調(diào)用(2)【例4.3】函數(shù)創(chuàng)建示例3:定義計(jì)算并返回第n階調(diào)和數(shù)(1+1/2+1/3+…+1/n)的函數(shù)defharmonic(n):#計(jì)算n階調(diào)和數(shù)(1+1/2+1/3+…+1/n)total=0.0foriinrange(1,n+1):total+=1.0/ireturntotal函數(shù)的調(diào)用(1)【例4.4】函數(shù)的調(diào)用示例1(triangle.py):先定義一個(gè)打印n個(gè)星號(hào)的無返回值的函數(shù)print_star(n),然后從命令行第一個(gè)參數(shù)中獲取所需打印的三角形的行數(shù)lines,并循環(huán)調(diào)用print_star()函數(shù)輸出由星號(hào)構(gòu)成的等腰三角形,每行打印1、3、5、...2*lines-1個(gè)星號(hào)importsysdefprint_star(n):print(("*"*n).center(50))

#打印n個(gè)星號(hào),兩邊填充空格,總寬度50lines=int(sys.argv[1])

#三角形行數(shù)foriinrange(1,2*lines,2):

#每行打印1、3、5、...、2*lines-1個(gè)星號(hào)print_star(i)函數(shù)名([形參列表]);函數(shù)的調(diào)用(2)【例4.5】函數(shù)的調(diào)用示例2先一個(gè)定義計(jì)算并返回第n階調(diào)和數(shù)(1+1/2+1/3+…+1/n)的函數(shù),輸出前n個(gè)調(diào)和數(shù)importsysdefharmonic(n):

#計(jì)算n階調(diào)和數(shù)(1+1/2+1/3+…+1/n)total=0.0foriinrange(1,n+1):total+=1.0/ireturntotaln=int(sys.argv[1])

#從命令行第一個(gè)參數(shù)中獲取調(diào)和數(shù)階數(shù)foriinrange(1,n+1):#輸出前n個(gè)調(diào)和數(shù)的值print(harmonic(i))函數(shù)的副作用函數(shù)的副作用讀取鍵盤輸入、產(chǎn)生輸出、改變系統(tǒng)的狀態(tài)等函數(shù)print_star(n)的副作用是向標(biāo)準(zhǔn)輸出寫入若干星號(hào)純函數(shù)(purefunction)接收一個(gè)或多個(gè)參數(shù),通過計(jì)算,返回一個(gè)值Lamda表達(dá)式和匿名函數(shù)>>>f=lambdax,y:x+y>>>type(f)#輸出:<class'function'>>>>f(12,34)#計(jì)算兩數(shù)之和。輸出:46>>>sorted([('Bob',75),('Adam',92),('Lisa',88)])#默認(rèn)按元組第一個(gè)元素排序[('Adam',92),('Bob',75),('Lisa',88)]>>>sorted([('Bob',75),('Adam',92),('Lisa',88)],key=lambdat:t[1])#按元組第二個(gè)元素排序[('Bob',75),('Lisa',88),('Adam',92)]lambda是一種簡(jiǎn)便的、在同一行中定義函數(shù)的方法。lambda實(shí)際上生成一個(gè)函數(shù)對(duì)象,即匿名函數(shù)Lamda表達(dá)式的基本格式為:lambdaargl,arg2...:<expression>【例4.6】匿名函數(shù)示例1【例4.7】匿名函數(shù)示例2

4.3參數(shù)的傳遞形式參數(shù)和實(shí)際參數(shù)聲明函數(shù)時(shí)所聲明的參數(shù),即為形式參數(shù),簡(jiǎn)稱形參調(diào)用函數(shù)時(shí),提供函數(shù)所需要的參數(shù)的值,即為實(shí)際參數(shù),簡(jiǎn)稱實(shí)參【例4.8】形式參數(shù)和實(shí)際參數(shù)示例(my_max1.py)程序運(yùn)行結(jié)果如下:1<211>8Traceback(mostrecentcalllast):··File“C:\python\ch04\my_max1.py“,line11<module>····my_max1(1)TypeError:mymax1()missing1requiredpositionalargument:’b’defmy_max1(a,b):ifa>b:print(a,'>',b)elifa==b:print(a,'=',b)else:print(a,'<',b)my_max1(1,2)x=11;y=8my_max1(x,y)my_max1(1)形式參數(shù)變量和對(duì)象引用傳遞聲明函數(shù)時(shí)聲明的形式參數(shù),等同于函數(shù)體中的局部變量,在函數(shù)體中的任何位置都可以使用局部變量和形式參數(shù)變量的區(qū)別在于,局部變量在函數(shù)體中綁定到某個(gè)對(duì)象;而形式參數(shù)變量則綁定到函數(shù)調(diào)用代碼傳遞的對(duì)應(yīng)實(shí)際參數(shù)對(duì)象Python參數(shù)傳遞方法是傳遞對(duì)象引用,而不是傳遞對(duì)象的值傳遞不可變對(duì)象的引用(1)如果函數(shù)體中修改對(duì)象的值,其結(jié)果實(shí)際上是創(chuàng)建了一個(gè)新的對(duì)象defswap(x,y):x,y=y,xx=1;y=2swap(x,y)print(x,y)【例4.9】傳遞不可變對(duì)象的引用示例(swap1.py):錯(cuò)誤的交換函數(shù)在本示例中,x指向整數(shù)對(duì)象1,y指向整數(shù)對(duì)象2,當(dāng)調(diào)用函數(shù)swap(x,y)后,在函數(shù)體內(nèi),執(zhí)行了“x,y=y,x”語(yǔ)句,在函數(shù)體內(nèi)的x指向整數(shù)對(duì)象2,y指向整數(shù)對(duì)象1。但是,當(dāng)函數(shù)調(diào)用完畢返回主程序時(shí),x仍然指向?qū)ο?,y仍然指向?qū)ο?,在Python語(yǔ)言中,一個(gè)函數(shù)不能改變一個(gè)不可改變對(duì)象(例如整數(shù)、浮點(diǎn)數(shù)、布爾值和字符串)的值(即函數(shù)無法產(chǎn)生副作用)。其內(nèi)存示意圖如圖4-3所示。傳遞不可變對(duì)象的引用(2)【例4.10】傳遞可變對(duì)象的引用示例(swap2.py):正確的交換函數(shù)defswap2(s,i,j):s[i],s[j]=s[j],s[i]s=[1,2]swap2(s,0,1)print(s)在本示例中,s指向列表對(duì)象[1,2],當(dāng)調(diào)用函數(shù)swap(s,0,1)后,在函數(shù)體內(nèi),s指向表對(duì)象[1,2],執(zhí)行了“s[i],s[j]=s[j],s[i]”語(yǔ)句,列表對(duì)象[1,2]改變?yōu)閇2,1]。當(dāng)函數(shù)調(diào)用完畢返回主程序后,s指向列表對(duì)象[2,1]。其內(nèi)存示意圖如圖4-4所示??蛇x參數(shù)defmy_sum1(mid_score,end_score,mid_rate=0.4):#期中成績(jī)、

#期末成績(jī)、期中成績(jī)權(quán)重。基于期中成績(jī)、期末成績(jī)和權(quán)重計(jì)算總評(píng)成績(jī)score=mid_score*mid_rate+end_score*(1-mid_rate)print(format(score,'.2f'))#輸出總評(píng)成績(jī),保留2位小數(shù)my_sum1(88,79)

#期中成績(jī)權(quán)重為默認(rèn)的40%my_sum1(88,79,0.5)

#期中成績(jī)權(quán)重設(shè)置為50%在聲明函數(shù)時(shí),如果希望函數(shù)的一些參數(shù)是可選的,可以在聲明函數(shù)時(shí)為這些參數(shù)指定默認(rèn)值調(diào)用該函數(shù)時(shí),如果沒有傳入對(duì)應(yīng)的實(shí)參值,則函數(shù)使用聲明時(shí)指定的默認(rèn)參數(shù)值【例4.11】可選參數(shù)示例(my_sum1.py):基于期中成績(jī)和期末成績(jī),按照指定的權(quán)重計(jì)算總評(píng)成績(jī)程序運(yùn)行結(jié)果如下:82.6083.50位置參數(shù)和命名參數(shù)函數(shù)調(diào)用時(shí),實(shí)參默認(rèn)按位置順序傳遞形參。按位置傳遞的參數(shù)稱之為位置參數(shù)函數(shù)調(diào)用時(shí),也可以通過名稱(關(guān)鍵字)指定傳入的參數(shù),例如:my_max1(a=1,b=2);my_max1(b=2,a=1)按名稱指定傳入的參數(shù)稱為命名參數(shù),也稱之為關(guān)鍵字參數(shù)。使用關(guān)鍵字參數(shù)具有三個(gè)優(yōu)點(diǎn):參數(shù)按名稱意義明確;傳遞的參數(shù)與順序無關(guān);如果有多個(gè)可選參數(shù),則可以選擇指定某個(gè)參數(shù)值在帶星號(hào)的參數(shù)后面聲明的參數(shù)強(qiáng)制為命名參數(shù),如果這些參數(shù)沒有默認(rèn)值,且調(diào)用時(shí)必須使用命名參數(shù)賦值,則會(huì)引發(fā)錯(cuò)誤如果不需要帶星號(hào)的參數(shù),只需要強(qiáng)制命名參數(shù),則可以簡(jiǎn)單地使用一個(gè)星號(hào),如deftotal(initial=5,*,vegetables)【例4.12】命名參數(shù)示例defmy_sum2(mid_score,end_score,mid_rate=0.4):#期中成績(jī)、期末成績(jī)、

#期中成績(jī)權(quán)重。基于期中成績(jī)、期末成績(jī)和權(quán)重計(jì)算總評(píng)成績(jī)score=mid_score*mid_rate+end_score*(1-mid_rate)print(format(score,'.2f'))#輸出總評(píng)成績(jī),保留2位小數(shù)#期中88,期末79,并且期中成績(jī)權(quán)重為默認(rèn)的40%。三種調(diào)用方式等價(jià)my_sum2(88,79)my_sum2(mid_score=88,end_score=79)my_sum2(end_score=79,mid_score=88)【例4.12】命名參數(shù)示例(my_sum2.py):基于期中成績(jī)和期末成績(jī),按照指定的權(quán)重計(jì)算總評(píng)成績(jī)程序運(yùn)行結(jié)果如下:82.6082.6082.60可變參數(shù)(VarArgs)(1)在聲明函數(shù)時(shí),通過帶星的參數(shù),如*param1,允許向函數(shù)傳遞可變數(shù)量的實(shí)參。調(diào)用函數(shù)時(shí),從那一點(diǎn)后所有的參數(shù)被收集為一個(gè)元組在聲明函數(shù)時(shí),也可以通過帶雙星的參數(shù),如**param2,允許向函數(shù)傳遞可變數(shù)量的實(shí)參。調(diào)用函數(shù)時(shí),從那一點(diǎn)后所有的參數(shù)被收集為一個(gè)字典帶星或雙星的參數(shù)必須位于形參列表的最后位置程序運(yùn)行結(jié)果如下:31528可變參數(shù)(VarArgs)(2)defmy_sum3(a,b,*c):

#各數(shù)字累加和total=a+bforninc:total=total+nreturntotalprint(my_sum3(1,2))

#計(jì)算1+2print(my_sum3(1,2,3,4,5))

#計(jì)算1+2+3+4+5print(my_sum3(1,2,3,4,5,6,7))#計(jì)算1+2+3+4+5+6+7【例4.13】可變參數(shù)示例1(my_sumVarArgs.py)。利用帶星的參數(shù)計(jì)算各數(shù)字累加和參數(shù)類型檢查當(dāng)使用不支持的類型參數(shù)調(diào)用函數(shù)時(shí),則會(huì)產(chǎn)生錯(cuò)誤。例如,my_average(a,b)函數(shù)傳遞的參數(shù)為str對(duì)象時(shí),Python在運(yùn)行時(shí)將拋出錯(cuò)誤TypeError用戶調(diào)用函數(shù)時(shí)必須理解并保證傳入正確類型的參數(shù)值定義函數(shù)時(shí),不用限定其參數(shù)和返回值的類型這種靈活性可以實(shí)現(xiàn)多態(tài)性,即允許函數(shù)適用于不同類型的對(duì)象,例如,my_average(a,b)函數(shù),即可以返回兩個(gè)int對(duì)象的平均值,也可以返回兩個(gè)float對(duì)象的平均值程序運(yùn)行結(jié)果如下:2114.4函數(shù)的返回值

return語(yǔ)句和函數(shù)返回值求若干數(shù)中最大值的方法一般如下:(1)將最大值的初值設(shè)為一個(gè)比較小的數(shù),或者取第一個(gè)數(shù)為最大值的初值。(2)利用循環(huán),將每個(gè)數(shù)與最大值比較,若此數(shù)大于最大值,則將此數(shù)設(shè)置為最大值defmy_max(a,b,*c):#求若干數(shù)中的最大值max_value=a#假設(shè)第一個(gè)數(shù)為最大值ifmax_value<b:#如果最大值小于b,則b為最大值max_value=bforninc:#循環(huán)迭代c中每個(gè)元素n,如果最大值小于n,則n為最大值ifmax_value<n:max_value=nreturnmax_value#利用return語(yǔ)句返回最大值#測(cè)試代碼print(my_max(1,2))#求(1,2)中的最大值print(my_max(1,7,11,2,5))#求(1,7,11,2,5)中的最大值【例4.14】函數(shù)的返回值示例(my_max2.py)。編寫函數(shù),利用return語(yǔ)句返回函數(shù)值,求若干數(shù)中的最大值返回多個(gè)值在函數(shù)體中使用return語(yǔ)句,可實(shí)現(xiàn)從函數(shù)返回一個(gè)值,并跳出函數(shù)。如果需要返回多個(gè)值,則可以返回一個(gè)元組importrandomdefrandomarray(n):#生成由n個(gè)隨機(jī)數(shù)構(gòu)成的列表a=[]foriinrange(n):a.append(random.random())returna#測(cè)試代碼b=randomarray(5)#生成由5個(gè)隨機(jī)數(shù)構(gòu)成的列表foriinb:print(i)

#輸出列表中每個(gè)元素【例4.15】編寫一個(gè)函數(shù),返回一個(gè)隨機(jī)列表。隨機(jī)列表(randomarray.py)。先編制一個(gè)函數(shù),生成由n個(gè)隨機(jī)整數(shù)構(gòu)成的列表,然后編寫測(cè)試代碼,生成并輸出由5個(gè)隨機(jī)整數(shù)構(gòu)成的列表各元素值4.5變量的作用域(1)全局變量、局部變量和類型成員變量全局變量:在一個(gè)源代碼文件中,在函數(shù)和類定義之外聲明的變量全局變量的作用域?yàn)槠涠x的模塊,從定義的位置起,直到文件結(jié)束位置通過import語(yǔ)句導(dǎo)入模塊,也可以通過全限定名稱“模塊名.變量名”訪問。或者通過from…import語(yǔ)句導(dǎo)入模塊中的變量并訪問TAX1=0.17

#稅率常量17%TAX2=0.2

#稅率常量20%TAX3=0.05

#稅率常量5%PI=3.14

#圓周率3.14【例4.16】全局變量定義示例(global_variable.py)變量的作用域(2)【例4.17】全局變量使用示例importglobal_variable#導(dǎo)入全局變量定義deftax(x):

#根據(jù)稅率常量20%計(jì)算納稅值returnx*global_variable.TAX2#測(cè)試代碼a=[1000,1200,1500,2000]foriina:

#計(jì)算并打印4筆數(shù)據(jù)的納稅值print(i,tax(i))程序運(yùn)行結(jié)果如下:1000200.01200240.01500300.02000400.0程序運(yùn)行結(jié)果如下:105100局部變量在函數(shù)體中聲明的變量(包括函數(shù)參數(shù))稱為局部變量,其有效范圍(作用域)為函數(shù)體如果在一個(gè)函數(shù)中定義的局部變量(或形式參數(shù)變量)與全局變量重名,則局部變量(或形式參數(shù)變量)優(yōu)先,即函數(shù)中定義的變量是指局部變量(或形式參數(shù)變量),而不是全局變量num=100

#全局變量deff():num=105

#局部變量print(num)

#輸出局部變量的值#測(cè)試代碼f();print(num)【例4.18】局部變量定義示例全局語(yǔ)句global(1)在函數(shù)體中,可以引用全局變量,但如果函數(shù)內(nèi)部的變量名是第一次出現(xiàn)且在賦值語(yǔ)句之前(變量賦值),則解釋為定義局部變量m=100n=200deff():print(m+5)#引用全局變量mn+=10

#錯(cuò)誤,n在賦值語(yǔ)句前面,

#解釋為局部變量(不存在)#測(cè)試代碼f()【例4.19】函數(shù)體錯(cuò)誤引用全局變量的示例全局語(yǔ)句global(2)【例4.20】全局語(yǔ)句global示例pi=3.141592653589793#全局變量e=2.718281828459045#全局變量defmy_func():globalpi#全局變量,與前面的全局變量pi指向相同的對(duì)象pi=3.14#改變了全局變量的值print('globalpi=',pi)#輸出全局變量的值e=2.718#局部變量,與前面的全局變量e指向不同的對(duì)象print('locale=',e)#輸出局部變量的值#測(cè)試代碼print('modulepi=',pi)#輸出全局變量的值print('modulee=',e)#輸出全局變量的值my_func()

#調(diào)用函數(shù)print('modulepi=',pi)#輸出全局變量的值,該值在函數(shù)中已被更改print('modulee=',e)#輸出全局變量的值非局部語(yǔ)句nonlocal在函數(shù)體中,可以定義嵌套函數(shù),在嵌套函數(shù)中,如果要為定義在上級(jí)函數(shù)體的局部變量賦值,可以使用nonlocal語(yǔ)句,表明變量不是所在塊的局部變量,而是在上級(jí)函數(shù)體中定義的局部變量。nonlocal語(yǔ)句可以指定多個(gè)非局部變量。例如nonlocalx,y,zdefouter_func():tax_rate=0.17

#上級(jí)函數(shù)體中的局部變量print('outerfunctaxrate=',tax_rate)#輸出上級(jí)函數(shù)體中局部變量的值definnner_func():nonlocaltax_rate#不是所在塊的局部變量,而是在上級(jí)函數(shù)體

#中定義的局部變量tax_rate=0.05

#上級(jí)函數(shù)體中的局部變量重新賦值print('innerfunctaxrate=',tax_rate)#輸出上級(jí)函數(shù)體中局部變量的值innner_func()#調(diào)用函數(shù)print('outerfunctaxrate=',tax_rate)#輸出上級(jí)函數(shù)體中局部變量的值

#(已更改)#測(cè)試代碼outer_func()【例4.21】非局部語(yǔ)句nonlocal示例4.6遞歸函數(shù)自調(diào)用函數(shù),在函數(shù)體內(nèi)部直接或間接地自己調(diào)用自己,即函數(shù)的嵌套調(diào)用是函數(shù)本身例如,非負(fù)整數(shù)的階乘定義為:n!=n×(n-1)×(n-2)×…×2×1,當(dāng)n=1時(shí),n!=1deffactorial(n):ifn==1:return1returnn*factorial(n-1)#測(cè)試代碼foriinrange(1,10):#輸出1~9的階乘print(i,'!=',factorial(i))【例4.22】使用遞歸函數(shù)實(shí)現(xiàn)階乘遞歸函數(shù)的原理(1)每個(gè)遞歸函數(shù)必須包括如下兩個(gè)主要部分。(1)終止條件。表示遞歸的結(jié)束條件,用于返回函數(shù)值,不再遞歸調(diào)用。例如,factorial()函數(shù)的結(jié)束條件為“n等于1”。(2)遞歸步驟。遞歸步驟把第n步的參數(shù)值的函數(shù)與第n-1步的參數(shù)值的函數(shù)關(guān)聯(lián)。例如,對(duì)于factorial(),其遞歸步驟為“n*factorial(n-1)”例如,調(diào)和數(shù)的計(jì)算公式為:Hn=1+1/2+...+1/n故可以使用遞歸函數(shù)實(shí)現(xiàn):(1)終止條件:Hn=1#當(dāng)n==1時(shí)(2)遞歸步驟:Hn=Hn-1+1/n#當(dāng)n>1時(shí)每次遞歸,n嚴(yán)格遞減,故逐漸收斂于1。遞歸函數(shù)的原理(2)【例4.23】使用遞歸函數(shù)實(shí)現(xiàn)調(diào)和數(shù)defharmonic(n):ifn==1:return1.0

#終止條件returnharmonic(n-1)+1.0/n#遞歸步驟#測(cè)試代碼foriinrange(1,10):

#輸出1~9階的調(diào)和數(shù)print('H',i,'=',harmonic(i))遞歸函數(shù)需要注意的問題必須設(shè)置終止條件缺少終止條件的遞歸函數(shù),將會(huì)導(dǎo)致無限遞歸函數(shù)調(diào)用,其最終結(jié)果是系統(tǒng)會(huì)耗盡內(nèi)存必須保證收斂否則,也會(huì)導(dǎo)致無限遞歸函數(shù)調(diào)用必須保證內(nèi)存和運(yùn)算消耗控制在一定范圍010302遞歸函數(shù)的應(yīng)用:最大公約數(shù)【例4.24】使用遞歸函數(shù)計(jì)算最大公約數(shù)(gcd.py)importsysdefgcd(p,q):

#使用遞歸函數(shù)計(jì)算p和q的最大公約數(shù)ifq==0:returnp

#如果q=0,返回preturngcd(q,p%q)#否則,遞歸調(diào)用gcd(q,p%q)#測(cè)試代碼p=int(sys.argv[1])

#p=命令行第一個(gè)參數(shù)q=int(sys.argv[2])

#q=命令行第二個(gè)參數(shù)print(gcd(p,q))

#計(jì)算并輸出p和q的最大公約數(shù)(1)終止條件:gcd(p,q)=p······#q=0時(shí)(2)遞歸條件:gcd(q,p%q)······#當(dāng)q>1時(shí)遞歸函數(shù)的應(yīng)用:漢諾塔終止條件。當(dāng)n==1時(shí),hanoi(n,a,b,c)為終止條件。即如果柱子a上只有一個(gè)圓盤,則可以直接將其移動(dòng)到柱子c上遞歸步驟。hanoi(n,a,b,c)可以分解為三個(gè)步驟:hanoi(n-1,a,c,b)、hanoi(1,a,b,c)和hanoi(n-1,b,a,c)。如果柱子a上有n個(gè)圓盤,可以看成柱子a上有一個(gè)圓盤(底盤)和(n-1)個(gè)圓盤,首先需要把柱子a上面的(n-1)個(gè)圓盤移動(dòng)到柱子b,即調(diào)用hanoi(n-1,a,c,b);然后,把柱子a上的最后一個(gè)圓盤移動(dòng)到柱子c,即調(diào)用hanoi(1,a,b,c);再將柱子b上的(n-1)個(gè)圓盤移動(dòng)到柱子c,即調(diào)用hanoi(n-1,b,a,c)每次遞歸,n嚴(yán)格遞減,故逐漸收斂于1大梵天創(chuàng)造世界的時(shí)候,在世界中心貝拿勒斯的圣廟里做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。稱之為漢諾塔大梵天命令婆羅門把圓盤從一根柱子上按大小順序重新擺放在另一根柱子上。并且規(guī)定,在三根柱子之間一次只能移動(dòng)一個(gè)圓盤,且小圓盤上不能放置大圓盤。這個(gè)游戲稱之為漢諾塔益智游戲漢諾塔益智游戲問題很容易使用遞歸函數(shù)實(shí)現(xiàn)。假設(shè)柱子編號(hào)為a、b、c,定義函數(shù)hanoi(n,a,b,c)表示把n個(gè)圓盤從柱子a移到柱子c(可以經(jīng)由柱子b),則有:010302【例4.25】使用遞歸函數(shù)實(shí)現(xiàn)漢諾塔問題(hanoi.py)#將n個(gè)從小到大依次排列的圓盤從柱子a移動(dòng)到柱子c上,柱子b作為中間緩沖defhanoi(n,a,b,c):ifn==1:print(a,'->',c)#只有一個(gè)圓盤,直接將圓盤從柱子a移動(dòng)到柱子c上else:hanoi(n-1,a,c,b)#先將n-1個(gè)圓盤從柱子a移動(dòng)到柱子b上(采用遞歸方式)hanoi(1,a,b,c)#然后將最大的圓盤從柱子a移動(dòng)到柱子c上hanoi(n-1,b,a,c)#再將n-1個(gè)圓盤從柱子b移動(dòng)到柱子c上(采用遞歸方式)#測(cè)試代碼hanoi(4,'A','B','C')4.7內(nèi)置函數(shù)的使用常用的Python內(nèi)置函數(shù)及其示例eval函數(shù)(動(dòng)態(tài)表達(dá)式的求值)expression是動(dòng)態(tài)表達(dá)式的字符串;globals和locals是求值時(shí)使用的上下文環(huán)境的全局變量和局部變量,如果不指定,則使用當(dāng)前運(yùn)行上下文>>>x=3>>>str_func=input("請(qǐng)輸入表達(dá)式:")請(qǐng)輸入表達(dá)式:x**2+2*x+1>>>eval(str_func)#對(duì)表達(dá)式3**2+2*3+1求值。輸出:16?exec函數(shù)(動(dòng)態(tài)語(yǔ)句的執(zhí)行)str是動(dòng)態(tài)語(yǔ)句的字符串;globals和locals是使用的上下文環(huán)境的全局變量和局部變量,如果不指定,則使用當(dāng)前運(yùn)行上下文>>>exec("foriinrange(10):print(i,end='‘)”)

#輸出:0123456789

0123456789通常,eval()用于動(dòng)態(tài)表達(dá)式求值,返回一個(gè)值;exec()用于動(dòng)態(tài)語(yǔ)句的執(zhí)行,不返回值?內(nèi)置map()函數(shù)(1)【例4.26】map()函數(shù)示例1:自定義函數(shù)is_odd,應(yīng)用該函數(shù)到可迭代對(duì)象的每一個(gè)元素,返回是否為奇數(shù)的可迭代對(duì)象結(jié)果>>>defis_odd(x):

returnx%2==1>>>list(map(is_odd,range(5)))#輸出:[False,True,False,True,False]map()函數(shù)實(shí)現(xiàn)為內(nèi)置的map(f,iterable,...)可迭代對(duì)象,將函數(shù)f應(yīng)用于可迭代對(duì)象,返回結(jié)果為可迭代對(duì)象>>>list(map(abs,[1,-3,5,6,-2,4]))#輸出:[1,3,5,6,2,4]【例4.27】map()函數(shù)示例2:使用內(nèi)置函數(shù)abs,返回絕對(duì)值列表內(nèi)置map()函數(shù)(2)【例4.28】map()函數(shù)示例3:使用內(nèi)置函數(shù)str,返回元素的字符串表示形式>>>list(map(str,[1,2,3,4,5]))#輸出:['1','2','3','4','5']>>>defgreater(x,y):

returnx>y>>>list(map(greater,[1,5,7,3,9],[2,8,4,6,0]))[False,False,True,False,True]【例4.29】map()函數(shù)示例4:使用帶兩個(gè)參數(shù)的自定義函數(shù),實(shí)現(xiàn)兩個(gè)列表的元素依次比較的運(yùn)算結(jié)果內(nèi)置filter()函數(shù)【例4.31】filter()函數(shù)示例2:返回三位數(shù)的回文數(shù)(正序和反序相同)可迭代對(duì)象>>>defis_palindrome(x):

ifstr(x)==str(x)[::-1]:

returnx>>>list(filter(is_palindrome,range(100,1000)))filter()函數(shù)實(shí)現(xiàn)為內(nèi)置的filter(f,iterable)可迭代對(duì)象(參見第9章),將函數(shù)f應(yīng)用于每個(gè)元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素,返回結(jié)果為可迭代對(duì)象>>>defis_odd(x):

returnx%2==1>>>list(filter(is_odd,range(10)))#輸出:[1,3,5,7,9]【例4.30】filter()函數(shù)示例1:返回奇數(shù)的可迭代對(duì)象4.8綜合應(yīng)用:turtle模塊繪制復(fù)雜的圖形【例4.32】使用海龜繪圖繪制等邊三角形、正方形、正五邊形、……、正十邊形等多邊形(polygon.py)importturtle#導(dǎo)入turtle模塊defdraw_polygon(sides,side_len):#繪制指定邊長(zhǎng)#長(zhǎng)度的多邊形foriinrange(sides):turtle.forward(side_len)#繪制邊長(zhǎng)turtle.left(360.0/sides)#旋轉(zhuǎn)角度defmain():foriinrange(3,11):#繪制等邊三角形、正方形、

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論