什么是高階函式:一個函式可以作為引數傳給另外一個函式(一個函式可以用來接收另一個函式作為引數),或者一個函式的回傳值為另外一個函式(若回傳值為該函式本身,則為遞回),滿足其一則為高階函式,函式的形參位置必須接受一個函式物件,
代碼理解高階函式的含義:
1 '''函式當做引數被傳遞到另個函式是什么樣的,把abs()函式賦值給了f變數,接下來就可以像使用abs()函式本身那樣使用f變數了,區別只是換了個名字而已''' 2 3 f = abs # 將求絕對值的abs函式賦值給f變數 4 f(-123) # f變數等同于abs函式的功能和性質,區別只是換了個別名 5 print(f(-123)) # 輸出結果 123 6 print(type(f)) # <builtin_function_or_method> 查看下這個f變數的型別,顯示為內置函式,因為它的真身就是內置abs()函式 7
8 '''這說明變數可以指向函式,既然變數可以指向函式,而我們知道函式的引數可以接收變數,也就是說一個函式可以接收另一個函式作為引數,一起來看看下面這個例子''' 9 def add_(a, b, f_): 10 return f_(a) + f_(b) # 在本例中等同于 abs(a) + abs(b) 11 12 result = add_(-10, -20, abs) # 這里把python內置函式abs作為引數傳遞給add_ 13 print(result) # 30
代碼演示高階函式兩種場景:
1 # 高階函式之 ---》引數為函式 2 def bar(): 3 print("in the bar..") 4 def foo(func): 5 func() 6 print("in the foo..") 7 8 foo(bar) 9 10 11 # 高階函式之 ---》回傳值為函式 12 def bar(): 13 print("in the bar..") 14 def foo(func): 15 print("in the foo..") 16 return bar 17 res=foo(bar) 18 res() 19 20 '''以上兩個示例中,函式foo()為高階函式,示例一中函式bar作為foo的引數傳入;示例二中函式bar作為foo的回傳值,
注意:函式名(例如bar 、foo)-->其為該函式的記憶體地址;函式名+括號(例如 bar()、foo() )-->呼叫該函式'''
python里的高階函式有 filter、map、reduce、sorted、匿名函式lambda,遞回函式等,
1). map函式
功能:map函式接收的是兩個引數,接收一個函式 f 和一個或多個序列list,其功能是將序列中的值處理再依次回傳至新串列內,其回傳值為一個迭代器物件,
語法格式:map(function, iterable,[iterable1, ...iterablen]):
引數:(1).function: 函式物件 ;(2).iterable:序列(可迭代)物件 (字串、串列、range...)
回傳值:得到的這個map物件是一個迭代器物件,屬于惰性序列的范疇,
代碼演示map實作原理:
1 # 需求:將lt = ['1','2','3','4','5'] 轉換成 [1,2,3,4,5] 2 3 # 代碼實作一:使用傳統技術來實作 4 lt = ['1','2','3','4','5','6'] 5 lt1 = [] 6 for i in lt: 7 num = int(i) 8 lt1.append(num) 9 print(lt1) # [1, 2, 3, 4, 5, 6] 由于串列屬于非惰性序列范疇,即可以直接列印看效果 10 11 12 # 代碼實作二:使用新技術來實作 13 # 思路步驟一:定義一個函式,功能:將str資料 --> int資料 14 import collections 15 lt = ['1','2','3','4','5','6']
16 def chr2Int(chr): 17 return int(chr) 18 19 mo = map(chr2Int,lt) # 這里的chr2Int后面不能加(),也不能傳參***** 20 print(map,type(mo)) # <class 'map'> <class 'map'> 21 print(isinstance(mo,collections.Iterator)) # True,驗證是否是迭代器物件,True才能使用next 22 print(next(mo)) # 1 23 print(list(mo)) # [2, 3, 4, 5, 6] 將map物件(惰性的)轉換為list物件(非惰性的) 24 25 26 #代碼實作三:終極操作 27 print(list(map(chr2Int,lt))) #[1, 2, 3, 4, 5, 6] 28 print(list(map(int,lt)) #[1, 2, 3, 4, 5, 6] 29 30 '''map(int,lt):執行程序如下: 31 1).lt --> 取出第一個元素:'1'當做實際引數傳遞給int函式的形參位置 --> int('1'),將轉換以后的結果:1保留到map物件的第一個元素位置 32 2).lt --> 取出第二個元素:'2'當做實際引數傳遞給int函式的形參位置 --> int('2'),將轉換以后的結果:2保留到map物件的第二個元素位置 33 以此類推... 34 直到map函式執行完了,整個map物件才真正成型了...'''
代碼演示示例:
1 # 實體1: lt = [1,2,3,4,5] --> 得到:['1','2','3','4','5'] 2 3 lt = [1,2,3,4,5] 4 5 # 自定義函式:從int --》 str 6 def int2Str(i): 7 return str(i) 8 9 print(list(map(int2Str,lt))) # ['1', '2', '3', '4', '5'] 10 print(list(map(str,lt))) # ['1', '2', '3', '4', '5'] 11 print(list(map(lambda x: str(x),lt))) # ['1', '2', '3', '4', '5'] 12 13 14 # 實體2:lt = [1,2,3,4,5] --> 得到:[1,4,9,16,25] 15 16 lt = [1,2,3,4,5] 17 18 # 自定義函式:目標實作開方操作 19 def kaifang(num): 20 return num ** 2 21 22 print(list(map(kaifang,lt))) # [1, 4, 9, 16, 25] 23 print(list(map(lambda x: x ** 2,lt))) # [1, 4, 9, 16, 25],map結合匿名函式使用,用的比較多
2).reduce函式
功能:reduce函式也是一個引數為函式,一個為可迭代(序列)物件的高階函式,但reduce()傳入的函式必須接收兩個引數,reduce()對list的每個元素反復呼叫函式function,所以reduce()函式接收的引數和 map()類似,但是行為不同,reduce() 函式會對引數序列中元素進行累積,其回傳值為一個值而不是迭代器物件,故其常用與疊加、疊乘等,
語法格式:reduce(function, iterable[, iterable1,...,iterablen] [, initializer])
引數:function -- 函式,有兩個引數,iterable -- 可迭代物件,initializer -- 可選,初始引數
回傳值:為一個值,而不是迭代器物件
【注意】:reduce函式屬于functools模塊中的函式,所以需要顯示的先匯入functools模塊再使用from functools import reduce
代碼演示reduce實作原理:
1 from functools import reduce 2 3 '''當呼叫reduce(f,[1,3,5,7,9])時,reduce函式將做如下計算:由于f這個函式的功能是計算兩個元素的值,所以先計算頭兩個元素:f(1,3), 4 結果為4;再把結果和第3個元素計算:f(4,5),結果為9;再把結果和第4個元素計算:f(9,7),結果為16; 5 再把結果和第5個元素計算:f(16,9),結果為25;由于沒有更多的元素了,計算結束,回傳結果25,''' 6 def f(x, y): 7 return x + y 8 9 result = reduce(f, [1, 3, 5, 7, 9]) 10 print(result) # 25 11 12 13 '''reduce()**還可以接收第3個可選引數,作為計算的初始值,如果把初始值設為100,如計算:結果將變為125,
因為第一輪計算是:計算初始值和第一個元素:f(100, 1),結果為101,''' 14 reduce(f, [1, 3, 5, 7, 9], 100) 15 16 17 # 使用 lambda 匿名函式 18 reduce(lambda x, y: x+y, [1,3,5,7,9])
1 '''reduce函式執行順序:先將lsd中的第一和第二個元素傳入到fn中參與運算,運算后得到結果,再和第三個元素傳入到fn中參與運算,以此類推...''' 2 3 # 需求:得到元祖tp = (1,2,3,4)中元素的和值 4 5 '''首先自定義函式 --> add作用:對串列中的元素進行求和操作 def add(x,y) 6 然后使用reduce函式執行程序如下: 7 第一次:add(1,2) 8 第二次:add(add(1,2),3) 9 第三次:add(add(add(1,2),3),4)''' 10 11 # 代碼實作一:遞回的思想來實作 12 tp = (1,2,3,4) 13 def mySum(num): 14 if num == 1: 15 return 1 16 return num + mySum(num - 1) 17 18 print(mySum(4)) 19 20 21 # 代碼實作二:reduce函式實作 22 from functools import reduce 23 def add(x,y): 24 return x + y 25 26 res = reduce(add,tp) 27 28 print(res,type(res)) # 10 <class 'int'> 29 print(reduce(lambda x,y: x + y,tp)) # 10 30 print(sum(tp)) # 10 直接使用內置函式sum()了
代碼演示示例:
1 # 實體1:lt = [1,2,3,4] 得到其中元素的乘積 2 3 lt = [1,2,3,4] 4 print(reduce(lambda x,y: x * y,lt)) 5 6 # 實體2:從鍵盤讀入一個整數字串資料,例如:'12345',將其轉換為12345; 7 '''注意:不能直接使用int()來實作.思路:使用map和reduce配合來實作 8 步驟一:'12345' --》拆分為散裝資料:1 2 3 4 5 可以使用map來實作 9 步驟二:將map物件中的資料 1 2 3 4 5 組合成為 --> 12345 可以使用reduce來實作 10 ''' 11 from functools import reduce 12 13 str1 = '12345' 14 def chr2Int(str): 15 return int(str) 16 17 def zuhe(x,y): 18 return x * 10 + y 19 20 mo = map(chr2Int,str1) 21 num = reduce(zuhe,mo) 22 print(num,type(num)) #12345 <class 'int'> 23 24 25 #終極版: 26 print(reduce(lambda x,y: x * 10 + y,map(int,str1))) #12345
3).filter函式
功能:filter()函式也是接收兩個引數,接收一個函式和一個序列的高階函式,其主要功能是過濾,過濾掉不符合條件的元素,序列的每個元素作為引數傳遞給函式進行判,然后回傳 True 或 False,最后將回傳 True 的元素放到新序列中,filter的意思:在計算機領域中我們都稱為過濾器,
語法格式:filter(function, iterable)
引數:和map、reduce一樣理解,function:判斷函式,iterable :可迭代物件,
回傳值:一個惰性序列物件(filter物件,迭代器物件),例如串列
代碼演示示例:
1 # 示例1:lt = [1,2,3,4,5,6,7,8] --> 得到:[2,4,6,8] 2 3 lt = [1,2,3,4,5,6,7,8] 4 #代碼實作一:老技術 5 lt1 = [] 6 for i in lt: 7 if i % 2 == 0: 8 lt1.append(i) 9 10 print(lt1) 11 12 13 #代碼實作二:新技術(filter) 14 def func(o): 15 if o % 2 == 0: 16 return True 17 return False 18 19 fo =filter(func,lt) 20 21 print(fo,type(fo)) #<filter object at 0x0000000001E8F710> <class 'filter'> 22 print(list(filter(func,lt))) #[2, 4, 6, 8] 23 print(isinstance(fo,collections.Iterator)) #Ture 24 print(isinstance(fo,collections.Iterable)) #Ture 25 print(next(fo)) #2 26 print(next(fo)) #4 27 print(list(fo)) #[6, 8] 28 29 30 # 終極版: 31 print(list(filter(lambda x:x % 2 == 0,lt))) #[2, 4, 6, 8] 32 33 34 # 示例2:lt = [345,0,'abcde',1.2,0,3.14,0.0,'haha','hehe',True,False,[],(),{},{1,2,3},[10,20,30],{'name':'zs','age':30},None] 35 得到如下效果:lt = [345,'abcde',1.2,3.14,'haha','hehe',True,{1,2,3},[10,20,30],{'name':'zs','age':30}] 36 37 lt = [345,0,'abcde',1.2,0,3.14,0.0,'haha','hehe',True,False,[] 38 ,(),{},{1,2,3},[10,20,30],{'name':'zs','age':30},None] 39 40 print(list(filter(lambda x: bool(x),lt))) 41 #或者 42 print(list(filter(bool,lt))) 43 44 45 # 示例3:lt1 = ['aaaaaaaa','bbbbb','cccccc','ddd']得到如下效果:['aaaaaaaa','cccccc'] 46 47 lt1 = ['aaaaaaaa','bbbbb','cccccc','ddd'] 48 49 print(list(filter(lambda x: len(x) > 5,lt1)))
高階函式以及匿名函式之間的配合使用(練習):
1 '''模板一:lambda和filter的配合使用''' 2 # 需求:lt = [1,2,3,4,5,6,7,8,9] --> 得到[3,6,9] 3 4 print(list(filter(lambda x: x % 3 == 0,lt))) 5 6 7 '''模板二:lambda 和map的配合使用''' 8 # 需求:演示開平方操作 --> 容器物件:range 9 10 mo = map(lambda x: x ** 2,range(5)) 11 print(list(mo)) 12 13 14 '''模板三:在模板二的基礎上進行功能擴展:range(10),過濾以后保留的資料范圍大小為:(5,50)之間''' 15 16 mo = map(lambda x: x ** 2,range(10)) 17 fo = filter(lambda x: x > 5 and x < 50,mo) 18 print(list(fo)) 19 20 21 '''模板四:lambda 和reduce配合使用''' 22 # 求和值 23 import functools 24 25 lt = [1,2,3,4,5] 26 27 my_sum = functools.reduce(lambda x,y: x + y,lt) 28 print(my_sum) 29 30 31 '''模板五:求兩個串列物件中元素的和,回傳新串列: 32 lt1 = [1,2,3,4], lt2 = [5,6,7,8], 結果:lt3 = [6,8,10,12]''' 33 34 mo = map(lambda x,y: x + y,lt1,lt2) 35 print(list(mo)) 36 37 38 '''模板六:求字串中每個單詞的長度content = "welcome to shanghai", 結果:[7,2,8]''' 40 # 使用切割的思想:切完之后得到一個串列物件,內部元素["welcome","to","shanghai"] 41 words_list = content.split() 42 mo = map(len,words_list) 43 print(list(mo))
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/187340.html
標籤:Python
