版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Python程序設(shè)計授課教師:第7章函數(shù)式編程課程描述函數(shù)式編程是一種典范。本章首先對函數(shù)式編程的基本概念進行介紹,然后介紹Python語言是如何實現(xiàn)函數(shù)式編程的。本章知識點7.1函數(shù)式編程概述7.2Python函數(shù)式編程常用的函數(shù)7.3閉包函數(shù)7.4迭代器和生成器7.1函數(shù)式編程概述7.1.1函數(shù)式編程的概念7.1.2函數(shù)式編程的優(yōu)點7.1.1函數(shù)式編程的概念函數(shù)式編程是一種編程的基本風格,也就是構(gòu)建程序的結(jié)構(gòu)和元素的方式。函數(shù)式編程將計算過程看作是數(shù)學函數(shù),也就是可以使用表達式編程。在函數(shù)的代碼中,函數(shù)的返回值只依賴傳入函數(shù)的參數(shù),因此使用相同的參數(shù)調(diào)用函數(shù)2次,會得到相同的結(jié)果。1.頭等函數(shù)(First-classfunction)如果一個編程語言把函數(shù)視為頭等函數(shù),則可以稱其擁有頭等函數(shù)。擁有頭等函數(shù)的編程語言可以將函數(shù)作為其他函數(shù)的參數(shù),也可以將函數(shù)作為作為其他函數(shù)的返回值??梢园押瘮?shù)賦值給變量或存儲在元組、列表、字典、集合等數(shù)據(jù)結(jié)構(gòu)中。在擁有頭等函數(shù)的編程語言中,函數(shù)名沒有任何特殊的狀態(tài),而是將函數(shù)看作是function類型的二進制類型。2.高階函數(shù)(Higher-orderfunction)高階函數(shù)是頭等函數(shù)的一種實踐,它是可以將其他函數(shù)作為參數(shù)或返回結(jié)果的函數(shù)。例如,定義一個高階函數(shù)map(),有2個參數(shù),一個是函數(shù)func(),一個是列表list,map()函數(shù)將list里面的所有元素應用函數(shù)func(),并將處理結(jié)果組成一個列表list1,最后將list1作為map()函數(shù)的返回結(jié)果。3.純函數(shù)純函數(shù)具有如下特性:純函數(shù)與外界交換數(shù)據(jù)只有唯一渠道——參數(shù)和返回值。純函數(shù)不操作全局變量,沒有狀態(tài)、無I/O操作,不改變傳入的任何參數(shù)的值。理想情況下,不會給他傳入任何外部數(shù)據(jù)。很容易把一個純函數(shù)移植到一個新的運行環(huán)境,最多只需要修改類型定義即可。純函數(shù)具有引用透明性(ReferentialTransparency)。也就是說,對于同一個輸入值,它一定得到相同的輸出值,而與在什么時候、在什么情況下執(zhí)行該函數(shù)無關(guān)。7.1.2函數(shù)式編程的優(yōu)點1.便于進行單元測試2.便于調(diào)試3.適合并行執(zhí)行7.2Python函數(shù)式編程常用的函數(shù)7.2.1lambda表達式7.2.2map()函數(shù)7.2.3filter()函數(shù)7.2.4reduce()函數(shù)7.2.5zip()函數(shù)7.2.6普通編程方式與函數(shù)式編程的對比7.2.1lambda表達式lambda函數(shù)也是一種匿名函數(shù),是從數(shù)學里的λ演算得名的。λ演算可以用來定義什么是一個可計算函數(shù)。匿名函數(shù)并非沒有名字,而是將函數(shù)名作為函數(shù)結(jié)果返回。1.lambda函數(shù)Python的lambda表達式的函數(shù)體只能有唯一的一條語句,也就是返回值表達式語句。其語法如下:返回函數(shù)名=lambda參數(shù)列表:函數(shù)返回值表達式語句例如,下面的lambda表達式可以計算x、y和z等3個參數(shù)的和:sum=lambdax,y,z:x+y+z可以使用sum(x,y,z)調(diào)用上面的lambda表達式?!纠?-1】使用lambda表達式的例子。sum=lambdax,y,z:x+y+zprint(sum(1,2,3))運行結(jié)果為:6【例7-1】中的lambda表達式相當于下面的函數(shù)。defsum(x,y,z): returnx+y+z2.lambda表達式序列可以將lambda表達式作為序列(如列表、元組或字典等)元素,從而實現(xiàn)跳轉(zhuǎn)表的功能,也就是函數(shù)的列表。lambda表達式序列的定義方法如下:序列名=[(lambda表達式1),(lambda表達式2),…]調(diào)用序列中l(wèi)ambda表達式的方法如下:序列名[索引](lambda表達式的參數(shù)列表)【例7-2】定義一個lambda表達式序列。第1個元素用于計算參數(shù)的平方,第2個元素用于計算參數(shù)的立方,第3個元素用于計算參數(shù)的四次方。代碼如下:Arr=[(lambdax:x**2),(lambdax:x**3),(lambdax:x**4)]print(Arr[0](2),Arr[1](2),Arr[2](2))程序分別計算并打印2的平方、立方和四次方。運行結(jié)果如下:48163.將lambda表達式作為函數(shù)的返回值可以在普通函數(shù)中返回lambda表達式?!纠?-3】定義一個函數(shù)math。當參數(shù)o等于1時返回計算加法的lambda表達式;當參數(shù)o等于2時返回計算計算減法的lambda表達式;當參數(shù)o等于3時返回計算乘法的lambda表達式;當參數(shù)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】運行結(jié)果如下:10+21210-2=810*2,=2010/2,=5.07.2.2map()函數(shù)map()函數(shù)用于將指定序列中的所有元素作為參數(shù)調(diào)用指定函數(shù),并將結(jié)果構(gòu)成一個新的序列返回。map函數(shù)的語法如下:結(jié)果序列=map(映射函數(shù),序列1[,序列2,…])在map()函數(shù)的參數(shù)中,可以有多個序列,這取決于映射函數(shù)的參數(shù)數(shù)量。序列1、序列2等序列中元素會按順序作為映射函數(shù)的參數(shù),映射函數(shù)的返回值將作為map()函數(shù)的返回序列的元素?!纠?-4】使用map()函數(shù)依次計算2、4、6、8和10的平方。arr=map(lambdax:x**2,[2,4,6,8,10])foreinenumerate(arr):print(e)本例中映射函數(shù)是一個lambda表達式,用于計算參數(shù)的平方。因為映射函數(shù)只有1個參數(shù),所以map()函數(shù)中只有1個序列參數(shù)。map()對序列參數(shù)應用lambda表達式,將計算結(jié)果作為序列返回?!纠?-4】運行結(jié)果如下:(0,4)(1,16)(2,36)(3,64)(4,100)【例7-5】在map()函數(shù)中對兩個序列進行處理。arr=map(lambdax,y:x+y,[1,3,5,7,9],[2,4,6,8,10])foreinenumerate(arr):print(e)本例中映射函數(shù)是一個有2個參數(shù)的lambda表達式,用于計算參數(shù)之和。因為映射函數(shù)有2個參數(shù),所以map()函數(shù)中有2個序列參數(shù)。map()對2個序列參數(shù)中對應位置的元素應用lambda表達式,將計算結(jié)果作為序列返回?!纠?-5】運行結(jié)果如下:(0,3)(1,7)(2,11)(3,15)(4,19)7.2.3filter()函數(shù)filter()函數(shù)可以對指定序列執(zhí)行過濾操作,具體定義如下:filter(函數(shù)function,序列sequence)函數(shù)function接受一個參數(shù),返回布爾值True或False。序列sequence可以是列表、元組或字符串。filter()函數(shù)以序列sequence中的每個元素為參數(shù)調(diào)用function函數(shù),調(diào)用結(jié)果為True的元素最后將作為filter()函數(shù)的結(jié)果返回?!纠?-6】使用filter()函數(shù)的例子。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】運行結(jié)果如下:(0,2)(1,4)(2,6)(3,8)(4,10)7.2.4reduce()函數(shù)reduce()函數(shù)用于將指定序列中的所有元素作為參數(shù),按一定的規(guī)則調(diào)用指定函數(shù)。reduce函數(shù)的語法如下:計算結(jié)果=reduce(映射函數(shù),序列)映射函數(shù)必須有2個參數(shù)。reduce()函數(shù)首先以序列的第1和第2個元素為參數(shù)調(diào)用映射函數(shù),然后將返回結(jié)果與序列的第3個元素為參數(shù)調(diào)用映射函數(shù)。以此類推,直至應用到序列的最后一個元素,將計算結(jié)果作為reduce()函數(shù)的返回結(jié)果?!纠?-7】使用reduce()函數(shù)計算2、4、6、8、10的和。fromfunctoolsimportreducedefmyadd(x,y):returnx+ysum=reduce(myadd,(2,4,6,8,10))print(sum)【例7-7】程序運行過程:(1)reduce()函數(shù)首先使用2和4為參數(shù)調(diào)用myadd()函數(shù),得到結(jié)果6。(2)使用結(jié)果6和序列的第3個元素6為參數(shù)調(diào)用myadd()函數(shù),得到結(jié)果12。(3)使用結(jié)果12和序列的第4個元素8為參數(shù)調(diào)用myadd()函數(shù),得到結(jié)果20。(4)使用結(jié)果20和序列的第5個元素10為參數(shù)調(diào)用myadd()函數(shù),得到結(jié)果30。7.2.5zip()函數(shù)zip()函數(shù)以一系列列表作為參數(shù),將列表中對應的元素打包成一個個元組,然后返回由這些元組組成的列表?!纠?-8】使用zip()函數(shù)的例子。a=[1,2,3]b=[4,5,6]zipped=zip(a,b)forelementinzipped:print(element)【例7-8】運行結(jié)果如下:(1,4)(2,5)(3,6)【例7-9】使用zip()函數(shù)時傳入?yún)?shù)長度不等的例子。a=[1,2,3]b=[4,5,6,7,8,9]zipped=zip(a,b)forelementinzipped:print(element)注意:調(diào)用zip()函數(shù)時以長度最短的列表長度為基準進行壓縮?!纠?-9】運行結(jié)果如下:(1,4)(2,5)(3,6)7.2.5zip()函數(shù)將打包結(jié)果前面加上操作符*,并以此作為參數(shù)調(diào)用zip()函數(shù),可以將打包結(jié)果解壓?!纠?-10】使用zip()函數(shù)將打包結(jié)果解壓的例子。a=[1,2,3]b=[4,5,6]zipped=zip(a,b)unzipped=zip(*zipped)forelementinunzipped:print(element)【例7-10】運行結(jié)果如下:(1,2,3)(4,5,6)7.2.6普通編程方式與函數(shù)式編程的對比【例7-11】以普通編程方式計算列表元素中正數(shù)之和。list=[2,-6,11,-7,8,15,-14,-1,10,-13,18]sum=0foriinrange(len(list)):iflist[i]>0:sum+=list[i]print(sum)運行結(jié)果如下:647.2.6普通編程方式與函數(shù)式編程的對比【例7-12】以函數(shù)式編程方式實現(xiàn)【例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普通編程方式與函數(shù)式編程的對比相比而言,函數(shù)式編程具有如下特點:(1)代碼更簡單。(2)數(shù)據(jù),操作,返回值都放在一起。(3)沒有循環(huán)體,幾乎沒有臨時變量,也就不用勞神去分析程序的流程行尾數(shù)據(jù)變化過程。(4)代碼用來描述要做什么,而不是怎么去做。7.3閉包函數(shù)在Python中,閉包指函數(shù)的嵌套??梢栽诤瘮?shù)內(nèi)部定義一個嵌套函數(shù),將嵌套函數(shù)視為一個對象,所以可以將嵌套函數(shù)作為定義它的函數(shù)的返回結(jié)果。閉包的基本形式是:在函數(shù)F1中,定義F2,F(xiàn)2只能引用F1定義的變量,之后F1函數(shù)返回F2的函數(shù)名字。而后可以將F1的執(zhí)行結(jié)果賦給一個新的函數(shù)名,該函數(shù)可以在之后隨時執(zhí)行。
7.3閉包函數(shù)在Python中,閉包所需要具備的條件:必須有一個嵌套函數(shù)。嵌套函數(shù)必須引用外部函數(shù)中的變量。外部函數(shù)必須將嵌套函數(shù)作為返回值返回?!纠?-13】使用閉包的例子。deffunc_lib():defadd(x,y):returnx+yreturnadd#返回函數(shù)對象fadd=func_lib()print(fadd(1,2))運行結(jié)果:37.4迭代器和生成器7.4.1迭代器7.4.2生成器7.4.1迭代器迭代器是訪問序列內(nèi)元素的一種方式。迭代器對象從序列(列表、元組、字典、集合)的第一個元素開始訪問,直到所有的元素都被訪問一遍后結(jié)束。迭代器不能回退,只能往前進行迭代。1.iter()函數(shù)使用iter()函數(shù)可以獲取序列的迭代器對象,方法如下:
迭代器對象=iter(序列對象)使用next()函數(shù)可以獲取迭代器的下一個元素,方法如下:
next(迭代器對象)
如果所有元素均已經(jīng)返回過,則拋出StopIteration異常?!纠?-14】使用iter()函數(shù)的例子。list=[111,222,333]it=iter(list)print(next(it))print(next(it))print(next(it))運行結(jié)果如下:1112223332.enumerate()函數(shù)使用enumerate()函數(shù)可以將列表或元組生成一個有序號的序列。【例7-15】使用enumerate()函數(shù)的例子。list=[111,222,333]forindex,valinenumerate(list):print("第%d個元素是%s"%(index+1,val))運行結(jié)果如下:第1個元素是111第2個元素是222第3個元素是3337.4.2生成器生成器是一個特殊的函數(shù),它具有如下特點:(1)生成器
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 上海2025年上海城建職業(yè)學院招聘筆試歷年參考題庫附帶答案詳解
- 2026年游戲開發(fā)技術(shù)及游戲設(shè)計原理試題
- 2026年電氣自動化技術(shù)電氣控制原理專項題庫
- 2026年大學計算機基礎(chǔ)與應用技能考試題庫
- e板會課件導入黑屏問題
- 光大證券修訂制度
- 2026年P(guān)MP考試沖刺沖突管理案例全解析
- 2026年網(wǎng)絡(luò)營銷策略網(wǎng)絡(luò)廣告投放與效果評估練習題
- 2026年計算機網(wǎng)絡(luò)原理與技術(shù)應用實戰(zhàn)題庫
- 企業(yè)品牌建設(shè)策略手冊(標準版)
- GB/T 3672.1-2025橡膠制品的公差第1部分:尺寸公差
- 2025外研社小學英語三年級下冊單詞表(帶音標)
- 承包檳榔園合同轉(zhuǎn)讓協(xié)議書
- 鵬城實驗室雙聘管理辦法
- 隧道滲漏檢測技術(shù)-洞察及研究
- x探傷安全管理制度
- 財政分局對賬管理制度
- 噴水機車間管理制度
- 云師大附中 2026 屆高三高考適應性月考(一)-地理試卷(含答案)
- 商業(yè)銀行反洗錢風險管理自評估制度研究
- 2025年度法院拍賣合同模板:法院拍賣拍賣保證金退還合同
評論
0/150
提交評論