您好,登錄后才能下訂單哦!
本篇內容主要講解“Python的遞歸函數與匿名函數調用方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python的遞歸函數與匿名函數調用方法是什么”吧!
一. 遞歸函數
a) 引言:在一個函數中自己調用自己會怎么樣呢?會陷入無限的調用循環。為了解決該問題就需要使用遞歸。
b) 應用:
i. 案例分析:編寫一個函數,該函數接收一個整數n,然后計算輸出n的階乘。
1. 首先定義一個一個函數def factorial(n),該函數應該怎么實現呢?我們知道計算n的階乘有如下規律:n!=n*[(n-1)*[n-2]…*1]=n*(n-1)!
2. 函數實現步驟可以是:
def factorial(n):
1.計算(n-1)的階乘
2.返回step1的結果值*n
要完成第一步的事情,就是要計算(n-1)!。由于我們這個函數是計算n!,因此第一步也可以理解為,以n-1為參數,調用factorial函數。代碼就會變成:
def factorial(n):
1.factorial(n-1)
2.返回step1的結果值*n
在該代碼中,出現了在factorial函數中調用factorial函數的情況。出現了函數的遞歸。為了完善上述代碼,可以將代碼中的第二部也翻譯成代碼:
def factorial(n):
1. int result=factorial(n-1)
2. return result*n
但是問題也出現了,加入n=3,在fac(3)的內部會調用fac(2),在fac(2)中會調用fac(1),在fac(1)中會調用fac(0)-》fac(-1)……因此我們需要規定一個循環調用結束的條件。在當前程序中當參數n的值為1時,則計算1的階乘,到這一步就沒有必要繼續遞歸下去的必要了,因此n=1是,應當直接返回。
def factorial(n):
if(n==1):
return 1
int result=factorial(n-1)
return result*n
二. 匿名函數
a) 引言:當我們在創建函數的時,有的時候不需要顯示的定義函數,直接傳入匿名函數會更加的方便,這會省去我們挖空心思為函數命名的麻煩,也能少些不少的代碼,很多編程語言都提供匿名函數這種特性。匿名函數用好了,會起到畫龍點睛的效果,沒用好就容易畫虎不成反類犬,
b) 在Python中使用lambda關鍵字來創建匿名函數。所謂匿名,即不再使用def這種標準形式定義函數,需要注意的有:
i. lambda是一個表達式而不是一個代碼塊
ii. 僅僅能在lambda表達式中封裝有限的邏輯
iii. Lambda函數擁有自己的命名空間
c) 語法結構:lambda 參數:表達式 例如 lambda x:x*x, 冒號前的x表示的是參數,后面的表示函數的執行代碼,,它相當于下面的函數:
Def f(x): return x*x
d) 注意:
i. 匿名函數只能有一個表達式
ii. 不用也不能寫return語句,表達式的結果就是返回值
iii. 匿名函數也是一個函數對象,可以將其賦值給一個變量,然后通過變量來調用該函數。f=lambda x:x*x f(6)
三. 推導式:是一種獨特的推導式語法,可幫我們在某些場合寫出比較精簡炫酷的代碼。但是沒有它,也不會有太多的影響。
a) 分類:
i. 列表推導式
ii. 字典推導式
iii. 集合推導式
iv. 元組推導式?
b) 列表推導式:是一種快速生成列表的方式,其形式使用方括號括起來的一段語句。
i. 案例:lis=[x*x for x in range(1,10) ] 首先執行for循環,對于每一個x帶入x*x中進行運算,將運算的結果值逐一添加到一個新的列表內(x*x的式子中使用的變量必須為for中的x)。尤其可見,列表推導式為我們提供了一種在一行內實現較為復雜邏輯的生成列表的方法。其核心語法就是用中括號將生成的邏輯封裝起來。
ii. 案例:[x*x for x in range(1,11) if x%2==0] 通過增加if語句對x進行過濾
iii. 案例:dic={“k1”:”v1”,”k2”:”v2”} a=[k+”:”+v for k,v in dic.items()]
c) 字典推導式:列表推導式使用的是中括號,那么如果使用大括號則可以制造字典推導式
i. 案例:dic={x:x*2 for x in(2,4,6)} x:x*2中間的冒號左邊表示key右邊表示value
ii. 案例:也可以添加if子句
d) 集合推導式:大括號除了可以用作字典推導式還可以用作集合推導式,注意兩者差別。
i. 案例:a={x for x in “abcdefg” if x not in “abc”}
e) 元組推導式:那是用小括號的是不是元組推導式呢?no。在python中使用小括號的被叫做生成器的語法,在python中沒有元組推導式。
i. 如果想通過上述類似的方法生成元組,需要顯示調用元組的類型轉換函數tuple。t=tuple(x for x in range(10))
f) 面試題:
result = [lambda x: x + i for i in range(10)]
print(result[0](10))
答案是19,并且result[0~9](10)的結果都是19。這是因為函數具有調用時才查找變量的特性。在你沒調用它之前,它不會保存也不關心它內部變量的具體值。只有等到你調用它的時候,它才逐一去找這些變量的具體值。這里的result[0]被調用的時候,變量i已經循環完畢,變成9了,而不是想象中的動態0-9值。
那如果不想要這樣的結果,想要i是循環的值怎么辦?不要直接引用上層變量,把變量直接傳進來。
result = [lambda x, i=i: x + i for i in range(10)]
print(result[0](10))
四. 迭代器
a) 迭代:通過for循環遍歷對象的每一個元素的過程。For可以遍歷任何可迭代的對象。
b) 可迭代對象類型:list/tuple/string/dict/set/bytes。可以通過collections模塊的Iterable類型來判斷一個對象是否可迭代:
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代
c) 迭代器:是一種可以被遍歷的對象。特點如下:
i. 能調用next()函數。
ii. 使用iter()函數創建迭代器對象
iii. 迭代器對象從集合的第一個元素開始訪問,直到所有元素被訪問結束
iv. 只能往后遍歷,不能回溯
v. 案例:
>>> lis=[1,2,3,4]
>>> it = iter(lis) # 使用Python內置的iter()方法創建迭代器對象
>>> next(it) # 使用next()方法獲取迭代器的下一個元素
1
>>> next(it)
2
>>> next(it)
3
>>> next(it)
4
>>> next(it) # 當后面沒有元素可以next的時候,彈出錯誤
或者使用for循環遍歷迭代器:
lis = [1,2,3,4]
it = iter(lis) # 創建迭代器對象
for x in it: # 使用for循環遍歷迭代對象
print (x, end=" ")
迭代器的作用:除了可迭代的類型可以進行迭代外,在開發中也會遇到一些自定義的類型也有迭代的需求,即將自定義類型定義成迭代器類型即可(需要在類里實現__iter__()和__next__()方法,可供next和iter函數調用該對象)。for循環本質上就是通過不斷調用next()函數實現的
def iter(obj):
return obj.__iter__()
def next(obj):
return obj.__next__()
自定義迭代器類:
import random
class demo_iterator(object):
def __next__(self):
v = random.randint(0,10)
if v < 5:
raise StopIteration()
else:
return v
def __iter__(self):
return demo_iterator()
迭代作用:可以把這個元素流看做是一個有序序列,但卻不能提前知道序列的長度,只能不斷通過next()函數得到下一個元素,所以迭代器可以節省內存和空間。
五. 生成器
a) 引言:有時候,序列或集合內的元素的個數非常巨大,如果全制造出來并放入內存,對計算機的壓力是非常大的。比如,假設需要獲取一個10**20次方如此巨大的數據序列,把每一個數都生成出來,并放在一個內存的列表內,這是粗暴的方式,有如此大的內存么?如果元素可以按照某種算法推算出來,需要就計算到哪個,就可以在循環的過程中不斷推算出后續的元素,而不必創建完整的元素集合,從而節省大量的空間。在Python中,這種一邊循環一邊計算出元素的機制,稱為生成器:generator。
b) 語法格式:類似推導式,使用小括號
c) 案例:
>>> g = (x * x for x in range(1, 4))
>>> g
at 0x1022ef630>
可以通過next()函數獲得generator的下一個返回值,這點和迭代器非常相似:
>>> next(g)
1
但更多情況下,我們使用for循環。
for i in g:
print(i)
d) 關鍵字yield:
1. 用法:使用yield返回的函數會變成一個生成器。在調用生成器的過程中,每次遇到yield時,函數會暫停并保存當前所有的運行信息,返回yeild值。并在下一次運行next方法時從當前位置繼續執行。
到此,相信大家對“Python的遞歸函數與匿名函數調用方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。