高階函數(shù)

函數(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)式[]變成()就變成了生成式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容