1.匿名函數(shù)
匿名函數(shù)就是沒有函數(shù)名的函數(shù)(匿名函數(shù)可以看成類型是function的值和10,‘a(chǎn)bc’是同類東西)
注意:匿名函數(shù)本質(zhì)還是函數(shù)腰池,函數(shù)中除了函數(shù)聲明語法外其他的都使用匿名函數(shù)
1)語法:
函數(shù)名 = lambda 參數(shù)列表:返回值
2)說明
lambda - 關(guān)鍵字
參數(shù)列表 - 參數(shù)名1肥荔,參數(shù)名2,...(不用括號括起來)
:- 固定寫法后面不產(chǎn)生縮進
返回值 - 任何有結(jié)果的表達式 ; 它是匿名函數(shù)的函數(shù)體惠爽,相當(dāng)于普通函數(shù)的return語句
3)調(diào)用匿名函數(shù):保存匿名函數(shù)值的變量(實參列表)
4)參數(shù)
普通函數(shù)中除了用‘參數(shù)名:類型’的形式來制定參數(shù)類型意外,其它的語法匿名函數(shù)都支持
sum1 = lambda x, y = 1: x + y
print_x = lambda x: x
print(sum1(1, 2))
print(print_x('dss'))
1.變量的作用域(變量在程序中能夠使用的范圍)
2.全局變量和局部變量
1)全局變量:沒有聲明在函數(shù)或者類里面的變量就是全局變量
作用域是從聲明開始到文件結(jié)束的任何位置
2)局部變量:聲明在函數(shù)中的變量就是局部變量(函數(shù)的參數(shù)相當(dāng)于聲明在函數(shù)中的變量)
作用域是從聲明開始到函數(shù)結(jié)束的任何位置
3)函數(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)存區(qū)域會自動釋放坐慰。
a = 10 # 全局變量
for x in range(5): # x - 全局變量
pass
4)global 和 nonlocal
是函數(shù)中的關(guān)鍵字较性,和return一樣只能在函數(shù)體中用
1)global - 在函數(shù)中聲明一個全局變量
global 變量
變量 = 值
a = 111 # 全局變量
def fun3():
# 聲明一個局部變量
a = 222
global b # global b變?yōu)槿肿兞?(如果函數(shù)外面有b則會修改函數(shù)外b的值)
b = 333
print('in', a, b)
fun3()
print('out', a, b)
2) nonlocal :在局部的局部去修改局部變量的值
nonlocal 變量
變量 = 值
a2 = 50
def f4():
a2 = 100
b2 = 100
def f41():
a2 = 500
nonlocal b2
b2 = 500
print('第二層函數(shù)里面:', a2, b2)
f41()
print('第一層函數(shù)', a2, b2)
f4()
# print(a2) # NameError: name 'a2' is not defined
1.遞歸函數(shù)
自己調(diào)用自己的函數(shù)(函數(shù)體中調(diào)用當(dāng)前函數(shù))
循環(huán)能做的事情,遞歸都能做
# def f1():
# print('sssssssss')
# f1()
# f1() # RecursionError: maximum recursion depth exceeded while calling a Python object
2.怎么寫遞歸
第一步:找臨界值(調(diào)用遞歸函數(shù)(循環(huán))結(jié)束的條件)
第二步:找關(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)的功能
注意:能用循環(huán)解決的問題就不要用遞歸(消耗內(nèi)存和cpu過多)
# 遞歸函數(shù):1 + 2 + 3 + ...+ n
def sum1(n):
# 臨界值 1
if n == 1:
return 1
return n + sum1(n - 1)
print(sum1(100))
# 斐波那契序列
# 1赞咙, 1, 2糟港, 3攀操, 5,8, 13
# 遞歸函數(shù)求斐波那契序列的第n個數(shù)
def sequ(n):
if n == 1 or n == 2:
return 1
return sequ(n - 2) + sequ(n - 1)
print(sequ(6))
# 練習(xí):用遞歸實現(xiàn)向下的直角三角形
def poto(n):
if n == 1:
return '*'
else:
print(n * "*")
return poto(n-1)
print(poto(9))
1.迭代器(iter)
迭代器作為容器可以保存多個數(shù)據(jù)秸抚;數(shù)據(jù)的來源:1)將其它序列轉(zhuǎn)換成迭代器速和,2)生成器產(chǎn)生
1)將其它序列轉(zhuǎn)換成迭代器
iter1 = iter('abc')
print(iter1, type(iter1)) # <str_iterator object at 0x000002D06BA2FC88> <class 'str_iterator'>
iter2 = iter([12, 30, 90])
print(type(iter2)) # <class 'list_iterator'>
2.獲取元素
不管用那種方式去獲取了元素的值,那么這個元素在迭代器中就不存在了
1)獲取單個元素:
next(迭代器)剥汤、迭代器.next() ->獲取迭代器中第一個元素
當(dāng)取完所有迭代器中的數(shù)據(jù)之后再用next(迭代器)或迭代器.next()去獲取元素會報錯 # StopIteration
2)遍歷
iter3 = iter('hello')
print(next(iter3)) # h
print(next(iter3)) # e
print(iter3.__next__()) # l
iter3 = iter('hello')
print(next(iter3))
for i in iter3:
print('for颠放;', i)
1.什么是生成器
1)生成器就是迭代器的一種
2)調(diào)用一個帶有yield關(guān)鍵字的函數(shù)就可以得到一個生成器
(如果一個函數(shù)中有yield關(guān)鍵字:a.調(diào)用函數(shù)不會執(zhí)行函數(shù)體;b.函數(shù)表達式的值不是函數(shù)的返回值)
1.創(chuàng)建生成器
def func1():
yield
print('=====')
return 100
gen1 = func1() # gen1就是一個生成器對象
print('外部', gen1) # 外部 <generator object func1 at 0x000002102ADDA948>
for i in gen1:
print(i)
2.生成器產(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ù)到函數(shù)結(jié)束都沒有遇到y(tǒng)ield就會報錯(StopIteration)
def func1():
print('++++++')
yield 1
print('----------')
yield 100 # yield 后面可以跟數(shù)據(jù)且同一個函數(shù)可以有多個yild
gen2 = func1()
print(gen2) # <generator object func1 at 0x000002135E4CAAC8>
print(next(gen2))
# ++++++
# 1
print(next(gen2))
# ----------
# 100
# print(next(gen2)) # StopIteration
# 練習(xí):
def f2():
for i in range(0, 100, 3):
yield i
print(next(f2()))
print(next(f2()))
print(next(f2()))
gen1 = f2()
print(next(gen1))
print(next(gen1))
print(next(gen1))