函數(shù)
1.匿名函數(shù)
"""
匿名函數(shù)就是沒有函數(shù)名的函數(shù):匿名函數(shù)可以看成是類型是function的值,和10,'abc'是同類的數(shù)據(jù)
注意: 匿名函數(shù)本質(zhì)還是函數(shù),函數(shù)中除了聲明函數(shù)以外其他的都使用
1)語法
lambda 參數(shù)列表: 返回值
2)說明
- lambda - 關(guān)鍵字
- 參數(shù)列表 - 參數(shù)名1,參數(shù)名2,...
- : - 固定
- 返回值 - 任何有結(jié)果的表達式,它是匿名函數(shù)的函數(shù)體,相當(dāng)于普通函數(shù)中的return語句
如:lambda x,y: x+y
調(diào)用(用一個變量名存儲):
fn1 = lambda x,y: x+y
print(fn1(2,3))
- 參數(shù)
普通函數(shù)中除了用'參數(shù)名:類型'的形式來指定參數(shù)類型以為,其他的語法匿名函數(shù)都支持
10 # int類型的數(shù)據(jù)
'abc' # str類型的數(shù)據(jù)
[1,2,3] # list類型的數(shù)據(jù)
lambda x:x # function類型的數(shù)據(jù),一般用做調(diào)用
str1 = 'abca'
str2 =str1.replace('a','A')
print(str2)
變量的作用域
1.變量的作用域:變量在程序中能夠使用的范圍
2.全局變量和局部便令
1)全局變量:沒有聲明在函數(shù)里面或者類里面的變量就是全局變量.
作用域是從聲明開始到文件結(jié)束的任何位置
2)局部變量:聲明在函數(shù)中的變量就是局部變量(函數(shù)的參數(shù)相當(dāng)于聲明在函數(shù)中的變量)
作用域是從聲明開始到函數(shù)結(jié)束的任何位置
函數(shù)調(diào)用過程(內(nèi)存方面):壓棧
當(dāng)調(diào)用函數(shù)的時候,系統(tǒng)會自動在內(nèi)存的棧區(qū)間為這個函數(shù)開辟一個獨立的內(nèi)純區(qū)域,
用來保存在函數(shù)中聲明的變量,當(dāng)函數(shù)調(diào)用結(jié)束后,這個內(nèi)存會自動釋放.
a = 10 # a是全局變量
for x in range(5): # x是全局變量
b = 20 # b是全局變量
pass
def fun2(y): # y是局部變量
z = 100 # z是局部變量
3.global和nonlocal
"""
global和nonlocal函數(shù)中的關(guān)鍵字,和return一樣只能在函數(shù)體中使用
1)global - 在函數(shù)中聲明一個全局變量
global 變量
變量 = 值
2)nonlocal - 在局部的局部中修改局部變量的值
nonlocal 變量
變量 = 值
# 這里的a是全局變量
a=10
def func3():
# 這里的a是局部變量
a = 20
# 將b定義為全局變量
global b
b = 30
print('函數(shù)內(nèi)部a',a) # 函數(shù)內(nèi)部a 20
print('函數(shù)內(nèi)部b',b) # 函數(shù)內(nèi)部b 30
func3()
print("函數(shù)外面a",a) # 函數(shù)外面a 10
print("函數(shù)外面b",b) # 函數(shù)外面b 30
def func4():
a1 = 100
def func5():
nonlocal a1
a1 = 200
print('函數(shù)中的函數(shù)中的a1',a1)
func5()
print('函數(shù)中的a1',a1)
func4()
函數(shù)遞歸
1.聲明遞歸函數(shù)
自己調(diào)用自己的函數(shù)(函數(shù)體中調(diào)用當(dāng)前函數(shù))
遞歸如果產(chǎn)生死循環(huán)達到一定程度會報錯
注意:
一般循環(huán)能做的事情遞歸都能做
循環(huán)能做的一般不要用遞歸做
遞歸會在某個點占用大量內(nèi)存
對cpu的消耗也很高
def func1(n):
if n>3:
n-=1
print(n)
func1(n)
else:
print('2')
# func1(5)
2.怎么寫遞歸函數(shù)
第一步:找臨界值(循環(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)實現(xiàn),根據(jù)關(guān)系用f(n-1)去實現(xiàn)f(n)的功能
# 用遞歸實現(xiàn):1+2+3+4+5+6+...+N
def sum1(n:int):
# 第一步:找臨界值
if n == 1:
return 1
# 第二步:sum1(n)和sum(n-1)
# sum1(n) = sum1(n-1)+n
return n + sum1(n-1)
# print(sum1(10))
練習(xí):用遞歸實現(xiàn)以下功能
def func2(n):
if n == 1:
return '*'+'\n'
return '*'*n + '\n'+ func2(n-1) # 倒打印
# return func2(n-1)+'*'*n + '\n' # 正打印
print(func2(5))
迭代器
1.迭代器(iter)
迭代器宛如一個深不見底的瓶子,看不見里面的數(shù)據(jù),只能每次取出看,取出后也放不進去了
迭代器作為容器可以保存多個數(shù)據(jù);
數(shù)據(jù)的來源:1)將其它序列轉(zhuǎn)換成迭代器,2)生成器
1)將其他序列轉(zhuǎn)換成迭代器
iter1 = iter('abc')
print(iter1,type(iter1))
iter2 = iter([12,23,43,54,54])
print(iter2,type(iter2))
2.獲取元素
不管用那種方式去獲取了元素的值,那么這個元素在迭代器中就不存在了
1)獲取單個元素:next(迭代器)/ 迭代器.next() -> 獲取迭代器中的第一個元素
2)遍歷:同樣取完就沒有了
for 變量 in 迭代器:
pass
iter3 = iter('hello')
print(next(iter3)) # h,取出就不在放回
print(next(iter3)) # e
print(next(iter3)) # l
print(iter3.__next__()) # l
print(iter3.__next__()) # o,此時已經(jīng)取完,迭代器為空,再取會報錯:StopIteration
生成器
1.什么是生成器
- 生成器就是迭代器中的一種
- 調(diào)用一個帶有yield關(guān)鍵字的函數(shù)就可以得到一個生成器
如果一個函數(shù)中有yield關(guān)鍵字:
a. 調(diào)用函數(shù)不會執(zhí)行函數(shù)體
b. 函數(shù)調(diào)用表達式的值不是函數(shù)的返回值,而是一個生成器對象
c. yield后邊可以跟數(shù)據(jù)桨吊,相當(dāng)于return娶眷;同一個函數(shù)可以有多個yield
2.怎么去創(chuàng)建一個生成器
def func1():
print('=====')
yield
return 100
gen1 = func1() #這的gen1就是一個生成器對象
# print('外部:',gen1) # 外部: <generator object func1 at 0x000001A3EF433570>
3.生成器產(chǎn)生數(shù)據(jù)的原理
1) 一個生成器能夠產(chǎn)生多少數(shù)據(jù),就看執(zhí)行完生成器對應(yīng)的函數(shù)的函數(shù)體會遇到幾次yield肺缕;yield后面的值就是生成器能夠產(chǎn)生的數(shù)據(jù)
2) 每次獲取生成器中的元素的時候趋观,都是先去執(zhí)行函數(shù)體垃沦,直到遇到y(tǒng)ield,并且將yield后面的值作為獲取元素的結(jié)果坤学;
并且保留結(jié)束的位置疯坤,下次獲取下一個值的時候,從上次結(jié)束的位置接著執(zhí)行函數(shù)體深浮,知道遇到y(tǒng)ield...
如果從開始執(zhí)行到函數(shù)結(jié)束到?jīng)]有遇到y(tǒng)ield压怠,就會報StopIteration的錯誤
注意:return后面的yield是執(zhí)行不了的,因為函數(shù)被終止飞苇,遇不到y(tǒng)ield
def func2():
print('++++++')
yield
print('--------')
yield 100
gen2 = func2()
print('外部:',next(gen2)) # 打泳薄:++++++ 外部: None
print('外部:',next(gen2)) # 打印:------ 外部: 100