一、匿名函數(shù)
- 匿名函數(shù)
就是沒(méi)有函數(shù)名的函數(shù);可以看成是類型是function的值,和10,'abc'是同類東西
注意:匿名函數(shù)還是函數(shù),除了聲明語(yǔ)法以外,其他適用于匿名函數(shù)
1)語(yǔ)法:
lambda 參數(shù)列表:返回值
2)說(shuō)明:
lambda - 關(guān)鍵字
參數(shù)列表 - 參數(shù)名1,參數(shù)名2,...
: - 固定寫(xiě)法
返回值 - 任何有結(jié)果的表達(dá)式;他是匿名函數(shù)的函數(shù)體,相當(dāng)于普通函數(shù)的rerun語(yǔ)句
調(diào)用匿名函數(shù):保存匿名函數(shù)的值的變量(實(shí)參列表)
3)參數(shù)
普通函數(shù)中除了用'參數(shù)名:類型'的形式來(lái)指定參數(shù)類型以外,其他語(yǔ)法匿名函數(shù)都支持
二、變量的作用域
- 變量的作用域:變量在程序中能夠使用的范圍
- 全局變量和局部變量
1)全局變量:沒(méi)有聲明在函數(shù)里面或者類里面的變量就是全局變量;
作用域:從聲明開(kāi)始到文件結(jié)束
a = 1 # 全局變量
x是全局變量
for x in range(5):
print(a)
print(x)
2)局部變量:聲明函數(shù)中的變量就是局部變量(函數(shù)的參數(shù)相當(dāng)于聲明在函數(shù)中的變量)
作用域:從聲明開(kāi)始到函數(shù)結(jié)束的任何位置
def func2(x1= 10, y1= 20):
z1 = 100
print(x1,y1,z1)
func2()
print(x1,y1,z1)
3)函數(shù)調(diào)用過(guò)程(內(nèi)存):壓棧
當(dāng)調(diào)用函數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)在內(nèi)存的棧區(qū)間為這個(gè)函數(shù)開(kāi)辟一個(gè)獨(dú)立的內(nèi)存取余,用來(lái)保存在函數(shù)中聲明的變量。
當(dāng)函數(shù)調(diào)用結(jié)束,這個(gè)內(nèi)存區(qū)域自動(dòng)釋放。
- global和nonlocal
global和nonlocal是函數(shù)中的關(guān)鍵字,和return一樣只能在函數(shù)體中使用
1)global - 在函數(shù)中聲明一個(gè)全局變量
global 變量
變量 = 值
2)nonlocal
在局部的局部中修改局部變量的值
nonlocal 變量
變量 = 值
三、函數(shù)遞歸
什么是遞歸函數(shù)
自己調(diào)自己的函數(shù)(函數(shù)體中調(diào)用當(dāng)前函數(shù))怎么寫(xiě)遞歸
第一步:找臨界值(循環(huán)結(jié)束的條件) - 在這兒需要結(jié)束函數(shù)
第二步:找關(guān)系 - 找f(n) 和f(n-1)的關(guān)系(找當(dāng)次循環(huán)和賞析循環(huán)的關(guān)系)
第三步:假設(shè)函數(shù)功能已經(jīng)實(shí)現(xiàn),根據(jù)關(guān)系用f(n-1)去實(shí)現(xiàn)f(n)的功能
注意:能用循環(huán)解決的問(wèn)題就不要用遞歸
練習(xí):用遞歸實(shí)現(xiàn)以下功能:
*****
****
***
**
*
def wangli(n):
if n == 1:
print('*')
return
wangli(n-1)
print(n * '*')
print(wangli(5))
四、迭代器
- 迭代器(iter)
迭代器作為容器可以保存多個(gè)數(shù)據(jù);
數(shù)據(jù)的來(lái)源:1)將其他序列轉(zhuǎn)換成迭代器;2)生成器
1)將其他序列轉(zhuǎn)換成迭代器
iter1 = iter('wangli')
print(iter1, type(iter1))
iter2 = iter([1, 2, 3, 4])
print(iter2, type(iter2))
- 獲取元素
不管用那種方式去獲取了元素的值,這個(gè)元素在迭代器中就不存在了
1)獲取單個(gè)元素:next(迭代器)、迭代器.next() - > 獲取迭代器中第一個(gè)元素
iter3 = iter('hello')
print(next(iter3))
print(next(iter3))
print(iter3.__next__())
如果迭代器為空,用next獲取元素會(huì)報(bào)錯(cuò)
2)遍歷
for 變量 in 迭代器:
pass
iter4 = iter('world')
for x in iter4:
print(x)
五、生成器
- 什么是生成器
1)生成器就是迭代器中的一種; - 調(diào)用一個(gè)帶有yield關(guān)鍵字的函數(shù)就可以得到一個(gè)生成器
1)如果一個(gè)函數(shù)中有yield關(guān)鍵字:
a.調(diào)用函數(shù)不會(huì)執(zhí)行函數(shù)體
b.函數(shù)調(diào)用表達(dá)式的值不是函數(shù)的返回值,而是一個(gè)生成器對(duì)象
2)生成器產(chǎn)生數(shù)據(jù)的原理
yield后可以跟數(shù)據(jù),同一個(gè)函數(shù)可以由多個(gè)yield
1)一個(gè)生成器能夠產(chǎn)生多少數(shù)據(jù)就看執(zhí)行完生成器對(duì)用的函數(shù)的函數(shù)體會(huì)遇到幾次yield
yield后面的值就是生成器能夠產(chǎn)生的數(shù)據(jù)
2)每次獲取生成器中元素時(shí),都是先去執(zhí)行函數(shù)體,直到遇到y(tǒng)ield,并且將yield后面的值作為獲取元素的結(jié)果;
并且保留結(jié)束的位置,下次獲取下一個(gè)的時(shí)候,從上次結(jié)束的位置接著執(zhí)行函數(shù)體,直到遇到y(tǒng)ield。
如果從開(kāi)始執(zhí)行到函數(shù)結(jié)束都沒(méi)有遇到y(tǒng)ield,就會(huì)報(bào)錯(cuò) StopIteration。