函數進階 遞歸函數 定義一個函數在函數的內部調用自身,如果不設置遞歸邊界,將死迴圈無限調用知道被pycharm等ide觀測到拋出異常終止 案例1: def fun(): if n == 0: return n else: return n*fun(n-1) # 在當前函數中,就是當n=0的時候停止調 ...
函數進階
遞歸函數
定義一個函數在函數的內部調用自身,如果不設置遞歸邊界,將死迴圈無限調用知道被pycharm等ide觀測到拋出異常終止
案例1:
def fun(): if n == 0: return n else: return n*fun(n-1) # 在當前函數中,就是當n=0的時候停止調用自身
純函數
純函數的概念,簡單來說,一個函數的返回結果只依賴於它的參數,並且在執行過程裡面沒有副作用(副作用請看到後面),就吧這個函數叫做純函數.
不管在什麼時候調用,傳入的參數相同,返回的結果就一定是一樣的.
純函數的三原則
- 變數都只在函數作用域內獲取,作為函數的參數傳入
- 不會產生副作用,不會改變被傳入的數據或者其他數據(全局變數)
- 相同的輸入保證相同的輸出
函數的副作用
副作用指函數被調用,完成函數既定的運算任務,但因為訪問了外部數據,尤其是因為對外部數據進行了操作,從而一定程度的改變了系統環境.
內置函數都是純函數,內置函數一般都是python中的內置類.
常用的內置函數 map函數,會根據提供的函數對指定序列做映射,filter函數,用於過濾序列
內置函數三劍客
filter
接收兩個參數,源碼記述中其本質為一個python類
第一個參數為含有計算規則的函數,第二個為可迭代對象.
案例1
def fun(): # return true return n < 5 li =[1,2,3,4,5,6,7,8] fil = filter(fun,li) # 兩個參數,第一個為函數,第二個為可迭代對象 # 執行邏輯,將可迭代對象中的元素遍歷傳入fun進行計算 print(type(fil)) # 返回為一個filter對象 print(list(fil)) # 可以通過轉換成list直接列印出來
其返回的即是列表li中所有滿足fun中小於5的值,且組合成一個新的序列.
map
同filter一樣,接收兩個參數,直接返回的是一個map對象.
filter會根據返回值判斷是否將值放入新的序列中,map則會直接將返回值拿過來,相當於將可迭代對象便利傳入func中並取到func運行之後的返回值.
使用場景常常為需要統一處理一批數據的時候.
案例2
li_source = [ i for in range(1,20)] def func(n): # 寫一個生成斐波那契數列的map函數方法 if n==1 or b==2 : return 1 else : return func(n-1) + func(n-2) fib = map(func,li_source) # 執行邏輯即是,便利li_source將其中元素迭代傳入func,按照其內部邏輯執行並返回
zip
主要用來打包數據,接收數據與前兩者不同,可以接收多個可迭代對象.
吧第一個可迭代元素遍歷與第二個可迭代對象打包成元組.
之後強轉為dict可以生成字典. 這種處理方式經常用來操作測試用例數據
長短不一的時候會自動取最短的,捨棄多餘項
匿名函數
匿名函數一種特殊的函數,不用def去定義,也不用給函數起名字,通過lambda表達式來定義.
這種函數稱為匿名函數
寫法 : lambda 參數 : 表達式 (返回值)
ex: lambda var : var1 *2
lambda a,b: a+b
前面相當於兩個沒有函數的參數,冒號後面相當於return,那麼如何傳參數呢?
匿名函數的適用場景 : 簡單的函數定義(只有一個表達式的那種)
我們按照傳統函數的思路來寫個傳參調用,
lamdba a,b : a+b(1,2)
但是匿名函數是不能按照傳統參數那樣直接在函數後添加()進行調用.
按照上面的寫法,會將()中的內容也當作表達式的一部分,並不會被當成是參數
解決方式是(lambda a,b:a+b)(參數1,參數2),通過()將函數體與參數分割開來即可,
匿名函數實戰的常規寫法,lambda是直接調用,直接使用,用完就丟,釋放記憶體,用變數去保存反而會浪費一塊記憶體去保存.
實例
iterator = filter(lambda x: x<10 ,li) # 所以lambda常常和filter,map一起使用, # 直接使用,用完就丟掉 print(list(iteraotr)) # 列表推導式中也可以使用 li2 = [(lambda x: x % 2==0)(i) for i in range(10)] # 其執行邏輯是,for迴圈遍歷出i的值為1-10,然後i作為參數傳入前面的匿名函數,最終生成值形成新列表
三目運算符
三木運算符,適用於一個條件判斷,成立,做A,不成立,做B
python版本的語法支持為
為真的時候的結果 if 判斷條件 else 為假的時候的結果 ( 與其他語言不同的地方是沒有冒號
寫起來會有中寫英語的感覺.
偏函數
什麼是偏函數呢?
python的內置模塊functools中提供了很多有用的功能,其中一個就是偏函數 partial
偏函數的作用
當函數的參數個數太多,需要進行簡化的時候,使用functools.partial可以創建一個新的函數,這個函數可以固定住原函數的部分參數,從而簡化調用時的使用.
在感覺上接近於對函數的在封裝,方便進行調用
partial()是不定長參數,可以封裝很多東西進去,函數寫第一位,後面則是參數位
上實例
li =[1,2,3,4,5,6,7,8,9] li1 =[1,2,3,4,5,6,7,8,9] li2 =[1,2,3,4,5,6,7,8,9] li3 =[1,2,3,4,5,6,7,8,9] li4 =[1,2,3,4,5,6,7,8,9] li5 =[