1.匿名函數(shù)
匿名函數(shù)就是沒有函數(shù)名的函數(shù),屬于function類型的數(shù)據(jù),匿名函數(shù)本質(zhì)還是函數(shù),函數(shù)中除了聲明語法以外,其他的都使用匿名函數(shù)
1)語法
lambda 參數(shù)列表:返回值
2)說明
lambda -- 關(guān)鍵字
參數(shù)列表 -- 參數(shù)名1,參數(shù)名2
: -- 固定
返回值 - 任何有結(jié)果的表達(dá)式;它匿名函數(shù)的函數(shù)體,相當(dāng)于普通函數(shù)中的return語句
調(diào)用匿名函數(shù): 保存匿名函數(shù)值的變量(實參列表)
3)參數(shù)
普通函數(shù)中除了用'參數(shù)名:類型'的形式來指定參數(shù)類型以外,其他的語法匿名函數(shù)都支持
2.全局變量和局部變量
1)全局變量
沒有聲明在函數(shù)內(nèi)部和類里面的變量就是全局變量,作用域是從聲明開始到文件結(jié)束的任何位置
2)局部變量
聲明在函數(shù)中的變量就是局部變量(函數(shù)的參數(shù)相當(dāng)于生命在函數(shù)中的位置),作用域從聲明函數(shù)到函數(shù)結(jié)束的任何位置
3)函數(shù)的調(diào)用過程(內(nèi)存):壓棧
當(dāng)調(diào)用函數(shù)的時候,系統(tǒng)會自動在內(nèi)存的棧區(qū)間未這個函數(shù)開辟一個獨(dú)立的內(nèi)存區(qū)域,用來保存在函數(shù)中聲明的變量,當(dāng)函數(shù)調(diào)用結(jié)束后這個內(nèi)存區(qū)域會自動釋放。
a = 10 # 全局變量
# x是全局變量
for x in range(5):
if False:
c = 100
b = 20 # 全局變量
print('循環(huán)里面:', a)
print('循環(huán)里面:', x)
print('外面:', b)
def func2(x1=10, y1=20):
z1 = 100 # 內(nèi)部變量
print('函數(shù)內(nèi)部:', x1, y1, z1)
func2()
3.global和nonlocal
global和nonlocal函數(shù)中的關(guān)鍵字,和return一樣只能在函數(shù)體中使用
1)global - 在函數(shù)中聲明一個全局變量
global 變量
變量 = 值
2)nonlocal: 在局部的局部中去修改局部變量的值
nonlocal 變量
變量 = 值
def func3():
# 這兒是在聲明一個局部變量a1
a1 = 222
print('函數(shù)里面a:', a1)
# 這兒的b1是全局變量,改變了b1的局部變量
global b1
b1 = 333
print('函數(shù)里面b:', b1)
func3()
```python
def func4():
a2 = 100
def func5():
a2 = 500
print('函數(shù)里面的函數(shù)里面a2:', a2) # 500
func5()
print('函數(shù)里面a2:', a2) # 100
func4()
def func4():
a2 = 100
nonlocal a2
def func5():
a2 = 500
print('函數(shù)里面的函數(shù)里面a2:', a2) # 100
func5()
print('函數(shù)里面a2:', a2) # 100
遞歸函數(shù)
"""
自己調(diào)自己的函數(shù)(函數(shù)體中調(diào)用當(dāng)前函數(shù))
循環(huán)能做的事情,遞歸都可以做
注意: 能用循環(huán)解決的問題就不要用遞歸
"""
# def func1():
# print('=====')
# func1()
#
#
# func1()
# 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)的功能
"""
# 用遞歸函數(shù)實現(xiàn): 1+2+3+...+n
def sum1(n):
# 第一步: 找臨界值
if n == 1:
return 1
# 第二步: sum1(n)和sum1(n-1)
# sum1(n) == 1+2+3+...+n-1+n
# sum1(n-1) == 1+2+3+ ... + n-1
# sum1(n) = sum1(n-1) + n
return sum1(n-1)+n
print(sum1(100))
# 用遞歸函數(shù)求斐波那契數(shù)列中第n個數(shù): 1, 1, 2, 3, 5, 8, 13, 21,...
def sequence(n):
if n == 1 or n == 2:
return 1
# 找關(guān)系:sequence(n)和sequence(n-1)
# sequence(n) = sequence(n-1) + sequence(n-2)
return sequence(n-1) + sequence(n-2)
print(sequence(1), sequence(2))
print(sequence(8))
迭代器(iterator)
迭代器作為容器可以保護(hù)多個數(shù)據(jù),迭代器的數(shù)據(jù)來源:1)將其他序列轉(zhuǎn)換成迭代器 2)生成器
1)將其他序列轉(zhuǎn)換成迭代器
iter1 = iter('abc')
print(iter1, type(iter1))
iter2 = iter([12, 30, 90])
print(type(iter2))
獲取迭代器中的元素
不管用哪種方式去獲取了元素的值,那么這個元素在迭代器中就不存在了
1)獲取單個元素:next(迭代器)、迭代器.next() -> 獲取迭代器中的第一個元素
iter3 = iter('hello')
print(next(iter3))
print(next(iter3))
print(next(iter3))
print(iter3.__next__())
2)遍歷:
for 變量 in 迭代器:
pass
iter4 = iter('world')
for x in iter4:
print(x)
生成器(generator)
什么是生成器
1)生成器是迭代器中的一種
2)調(diào)用一個帶有yield關(guān)鍵字的函數(shù)就可以得到一個生成器
如果一個函數(shù)中有yield關(guān)鍵字:
a.調(diào)用函數(shù)不會執(zhí)行函數(shù)體
b.函數(shù)調(diào)用表達(dá)式的值不是函數(shù)的返回值,而是一個生成器對象
# 1.怎么去創(chuàng)建一個生成器
def func1():
print('=======')
if False:
yield
return 100
gen1 = func1() # 這兒的gen1就是一個生成器對象
print('外部:', gen1) # 外部: <generator object func1 at 0x00000217DBEF3F48>
2.生成器產(chǎn)生數(shù)據(jù)的原理
1)一個生成器能夠產(chǎn)生多少數(shù)據(jù),就看執(zhí)行完生成器對應(yīng)的函數(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é)束都沒有遇到y(tǒng)ield,就會報StopIteration錯誤
def func2():
print('+++++')
yield 1
print('-----')
yield 100 # yield 后邊可以跟數(shù)據(jù);同一個函數(shù)可以有多個yield
gen2 = func2()
print(gen2)
print('函數(shù)外部:', next(gen2))
print('函數(shù)外部:', next(gen2))
# print('函數(shù)外部:', next(gen2)) # StopIteration
寫一個可以產(chǎn)生學(xué)號的生成器, 生成的時候可以自定制學(xué)號數(shù)字位的寬度和學(xué)號的開頭
study_id_creater('py',5) -> 依次產(chǎn)生: 'py00001', 'py00002', 'py00003',....
study_id_creater('test',3) -> 依次產(chǎn)生: 'test001', 'test002', 'test003',...
```python
def study_id_creater(str1, n):
for i in range(1, 6):
print(str1 + str(i).zfill(n))
study_id_creater('py', 5)
def study_id_creater(str1='abc', num=5):
for i in range(1, num+1):
yield str1 + str(i).zfill(7 - len(str1))
gen1 = study_id_creater()
print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))