18.python高階函數

来源:https://www.cnblogs.com/bonheur/archive/2020/03/01/12374412.html
-Advertisement-
Play Games

什麼是高階函數:一個函數可以作為參數傳給另外一個函數(一個函數可以用來接收另一個函數作為參數),或者一個函數的返回值為另外一個函數(若返回值為該函數本身,則為遞歸),滿足其一則為高階函數。函數的形參位置必須接受一個函數對象。 代碼理解高階函數的含義: 1 '''函數當做參數被傳遞到另個函數是什麼樣的 ...


什麼是高階函數:一個函數可以作為參數傳給另外一個函數(一個函數可以用來接收另一個函數作為參數),或者一個函數的返回值為另外一個函數(若返回值為該函數本身,則為遞歸),滿足其一則為高階函數。函數的形參位置必須接受一個函數對象。

代碼理解高階函數的含義:

 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))


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文實例講述了js實現iframe跨頁面調用函數的方法。分享給大家供大家參考。具體實現方法如下: 在項目中難免會遇到這樣一個問題就是頁面引入了IFrame並且需要父頁面調用子頁面函數或者子頁面需要調用父頁面函數。比如說:現在有兩個頁面parent.html和child.html。其中parent.h ...
  • Less 是一門 CSS 預處理語言,它擴展了 CSS 語言,增加了變數、Mixin(混入)、函數等特性,使 CSS 更易維護和擴展。 Less 可以運行在 Node 或瀏覽器端。 使用之前需要安裝,可以通過npm來進行安裝 $ npm install -g less 1.變數 LESS 允許開發者 ...
  • 效果圖 slider.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>slider</title> <link rel="stylesheet" href="../css/base.css"> <l ...
  • H5新增特性之語義化標簽 語義化標簽顧名思義標簽有自己的含義,瀏覽器或者程式員一看就知道是什麼。在HTML 5出來之前,我們用div來表示頁面章節,但是這些div都沒有實際意義。(即使我們用css樣式的id和class形容這塊內容的意義)。這些標簽只是我們提供給瀏覽器的指令,只是定義一個網頁的某些部 ...
  • 需求: 1.對某一列進行動態更新。 2.不能對錶格狀態更改,如選中狀態、當前頁數、篩選等。 這樣我們使用 draw 、ajax.reload 等都不能滿足第二個需求。幸好發現一個api cell().data() 可以實現上面的需求。對此進行了封裝來滿足需求。 解決: $.fn.dataTable. ...
  • 效果圖 slider2.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>slider</title> <link rel="stylesheet" href="../css/base.css"> < ...
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv ...
  • 設計模式是前人經驗的總結,教大家如何寫出可擴展、可讀、可維護的高質量代碼。設計模式與日常工作中的編碼有直接的關係,直接影響到開發人員的開發能力。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...