函數(shù)名就是變量名
- python定義函數(shù)其實(shí)就是定義一個(gè)類型是function的變量,函數(shù)名就是變量名。
- 函數(shù)也是數(shù)據(jù)類型,只支持一種操作,調(diào)用
def func1():
print('函數(shù)')
a = 10
print(type(a)) # <class 'int'>
print(type(b)) # <class 'function'>
b = a
print(b+20)
c = func1
c()
a = 100
func1 = 'abc'
高階函數(shù)
實(shí)參高階函數(shù)
- 被賦值變量可以作為函數(shù)的實(shí)參
- 參數(shù)是函數(shù)的函數(shù)就是實(shí)參高階函數(shù)
# 實(shí)參高階函數(shù)
def func3(x):
print(x(1,2))
func(lambda m,n:m+n)
系統(tǒng)提供的實(shí)參高階函數(shù)
- max/min/sorted 都是實(shí)參高階函數(shù),
- 參數(shù)key的要求:
- 參數(shù)key是一個(gè)函數(shù);被傳入的函數(shù)需要一個(gè)參數(shù)和一個(gè)返回值,
- 這個(gè)參數(shù)指向序列中的元素,
- 返回值是比較對(duì)象
# 實(shí)例1
# 實(shí)例2
# 練習(xí)1 獲取學(xué)生列表中成績最高的學(xué)生
student2 = [
{'name': '張三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
def func1(item):
return item['score']
print(max(student2,key=func1))
print(max(student2,key= lambda item:item['score']))
print(min(student2,key= lambda item:item['age']))
print(sorted(student2,key= lambda item:item['age']))
map 映射函數(shù) map(函數(shù),序列)將序列中所有的元素按照函數(shù)指定的規(guī)則生成新的元素保存在map對(duì)象中
函數(shù)的要求:需要一個(gè)參數(shù)和返回值,
參數(shù)指向的是序列中的元素,返回值就是用來替換原來元素的新元素-
應(yīng)用技巧:有時(shí)需要對(duì)列表中每個(gè)元素做一個(gè)相同的處理,得到新列表
例如:所有數(shù)據(jù)乘以3
? 所有字符串轉(zhuǎn)換為整數(shù)
? 兩個(gè)列表對(duì)應(yīng)值相加
map(func, list1, list2….)
函數(shù)func有幾個(gè)參數(shù),后面跟幾個(gè)列表
# 示例1:將列表list3中所有的元素都加1 -->
map(lambda item:item+1,list3 )
# 示例2: 將列表list3中的所有元素都轉(zhuǎn)換成對(duì)應(yīng)的字符串:['10','20','30']
map(lambda item:str(item),list1)
# 更好的寫法
map(str,list1) # 直接使用寫好的函數(shù)
list(map())
- reduce(函數(shù),序列,初始值=None)對(duì)序列中的元素按照函數(shù)提供的功能進(jìn)行累計(jì)的操作
- 函數(shù)需要兩個(gè)參數(shù)指向前兩個(gè)元素,需要一個(gè)返回值
- 第一個(gè)參數(shù)是初始值或上次運(yùn)算的結(jié)果
- 注意:如果沒有給初始值,函數(shù)中的第一個(gè)參數(shù)第一次取得是序列中的第一個(gè)元素,后面每次取到的是上次運(yùn)行的結(jié)果
from functools import reduce
list3 = [10,20,30,40]
# 示例1:求所有元素的和
print(reduce(lambda x,y:x+y,list3))
# 示例2:求所有元素的乘積
print(reduce(lambda x,y:x*y,list3)) #初始值有默認(rèn)值,用默認(rèn)值,沒有默認(rèn)值取第一個(gè)元素
# 示例3:求班級(jí)所有學(xué)生的總成績
student2 = [
{'name': '張三', 'age': 18, 'score': 89},
{'name': '小明', 'age': 29, 'score': 60},
{'name': '李四', 'age': 25, 'score': 90},
{'name': 'Tom', 'age': 19, 'score': 87}
]
print(reduce(lambda x,y:x+y['score'],student2)) # TypeError: unsupported operand type(s) for +: 'dict' and 'int'
print(reduce(lambda x,y:x+y['score'],student2,0))
#上面實(shí)例中沒有默認(rèn)值 x取none ..
返回值高階函數(shù)
- 返回值是函數(shù)的函數(shù)
def func1():
def func2(x,y):
return x+y
return func2
print(func1()(100,200))
裝飾器
- 裝飾器的作用:在不修改函數(shù)的情況下,給函數(shù)添加新的功能
- 裝飾器的本質(zhì)就是一個(gè)函數(shù),它既是實(shí)參高階函數(shù),也是返回值高階函數(shù)
- 裝飾器在批量處理函數(shù)
無參裝飾器
`def 函數(shù)名1(函數(shù)名2):
? def 函數(shù)名3(agrs,*kwagrs):
? 新功能代碼
? 返回值 = 函數(shù)名2(args,*kwargs)
? return 函數(shù)名3`
函數(shù)名1 - 裝飾器名字,命名的時(shí)候和這個(gè)裝飾器要添加的功能進(jìn)行關(guān)聯(lián)
函數(shù)名2 - 隨便命名,指向被添加功能的函數(shù);可以命名成 fn
函數(shù)名3 - 隨便命名,在原函數(shù)上添加完新的功能以后產(chǎn)生新的函數(shù)
新功能代碼 - 實(shí)現(xiàn)新加的功能的代碼
定義函數(shù)的時(shí)候args,*kwargs同時(shí)存在的意義不定長參數(shù)在調(diào)用的時(shí)候既可以使用位置參數(shù)也可以使用關(guān)鍵字參數(shù)
# 在函數(shù)開始執(zhí)行前打印'函數(shù)開始'
# 練習(xí)1 返回值是字符串的函數(shù),返回值中所有的小寫字母全部變成大寫字母
迭代器(iter)
什么是迭代器
- 迭代器是容器數(shù)據(jù)類型,只通過類型轉(zhuǎn)換和生成器來獲取迭代對(duì)象
迭代器存儲(chǔ)數(shù)據(jù)的特點(diǎn)
- 同時(shí)可以保存多個(gè)數(shù)據(jù),沒有辦法直接查看,而是需要先將數(shù)據(jù)從迭代器中取出來(取出之后不能放回去)
所有容器都可以轉(zhuǎn)換成迭代器
iter([1,23,44])
獲取迭代器中的元素
- 無論通過什么方式,只要將迭代器中的某個(gè)元素拿到了,那么這個(gè)元素在迭代器中不存在了。
# 遍歷
iter5 = iter('hello')
for x in iter5:
print(f'x:{x}')
# 獲取單個(gè)元素
next(迭代器對(duì)象) - 獲取迭代器中的一個(gè)元素(最上面的元素)
另一種寫法:迭代器對(duì)象.__next__
item6 = iter({'name':'張三','age':18})
print(next(iter3)) # name
print(next(iter3)) # age
# print(next(iter3)) # StopIteration
生成器
- 生成器就是迭代器,迭代器不一定是生成器
- 調(diào)用一個(gè)帶有yield的關(guān)鍵字的函數(shù)就可以得到一個(gè)生成器
生成器中的元素怎么產(chǎn)生的
產(chǎn)生數(shù)據(jù)的機(jī)器,你需要一個(gè)數(shù)據(jù)就給你一個(gè)數(shù)據(jù)
生成器能生產(chǎn)多少數(shù)據(jù)看執(zhí)行生成器對(duì)應(yīng)的函數(shù)的函數(shù)體會(huì)遇到幾次yield.
yield后面表達(dá)式的值就是生成器能夠產(chǎn)生的數(shù)據(jù)
# 示例1:創(chuàng)建一個(gè)生成器可以產(chǎn)生3個(gè)數(shù)分別是:10,100,78
def create_gender1():
yield 10
yield 100
yield 1000
gen2 = create_gender1()
print(next(gen2))
生成器產(chǎn)生數(shù)據(jù)的原理
- 當(dāng)獲取生成器元素的時(shí)候會(huì)自動(dòng)調(diào)用生成器關(guān)聯(lián)的函數(shù)
- 第一次是從函數(shù)開始的地方開始執(zhí)行直到遇到y(tǒng)ield為止,并且將yield后面的值作為為獲取到的數(shù)據(jù)
- 后面每次都是上一次結(jié)束為止開始執(zhí)行,直到遇到y(tǒng)ield。
- 如果全程沒有遇到y(tǒng)ield,就不會(huì)產(chǎn)生數(shù)據(jù)。next(生成器)會(huì)報(bào)錯(cuò)
生成式
列表推導(dǎo)式[]變成()就變成了生成式