函數(shù)
1、什么是函數(shù)
是實現(xiàn)某一特定功能的代碼塊的封裝
2蓬衡、函數(shù)的分類
系統(tǒng)函數(shù)(內(nèi)置函數(shù)) - 系統(tǒng)已經(jīng)實現(xiàn)了的函(已經(jīng)造好的機器),只需要調(diào)用就可以了
print函數(shù) input函數(shù) len函數(shù) sum函數(shù) max函數(shù)等等
自定義函數(shù):程序員自己聲明的函數(shù)(自己造機器)
3、函數(shù)的聲明(定義)
1)語法
def 函數(shù)名(形參列表):
"""
函數(shù)說明文檔
"""
函數(shù)體
2)說明
def —— python聲明函數(shù)的關鍵字
函數(shù)名 —— 和變量名一樣 見名知意 看到函數(shù)名大概知道是用來做什么的
() —— 固定寫法
形參列表 —— 變量1, 變量2, 變量3···變量名的個數(shù)可以是 0個或多個
它是將函數(shù)外面的值傳遞到函數(shù)里面
: —— 固定寫法
函數(shù)體 —— 和def保持一個縮進的箱歧,實現(xiàn)函數(shù)功能的一條或者多條語句
3)初學者聲明函數(shù)的步驟
一、確定函數(shù)的功能
二一膨、根據(jù)功能確定函數(shù)名
三呀邢、確定形參,看實現(xiàn)函數(shù)的功能需不需要從外面?zhèn)髦当鳎绻枰獋髦敌枰獛讉€
四价淌、實現(xiàn)函數(shù)功能
五、確定返回值
!!!!!)注意:函數(shù)在聲明的時候瞒津,函數(shù)體不會執(zhí)行
練習:寫一個函數(shù)求兩個數(shù)和
# 寫一個函數(shù)求兩個數(shù)和
def t_sum(x, y):
"""
函數(shù)說明文檔(功能說明)
:param x: (參數(shù)說明)
:param y:
:return: (返回值說明)
"""
print('求和')
print(x+y)
練習:聲明一個函數(shù) 實現(xiàn)求1+2+3+蝉衣。。巷蚪。n
# 聲明一個函數(shù) 實現(xiàn)求1+2+3+病毡。。屁柏。n
def sum1(n):
"""
求1+2+3+啦膜。。淌喻。n
:param x:
:return:
"""
i = 0
for x in range(n+1):
i += x
print(i)
sum1(10)
4僧家、函數(shù)的調(diào)用 使用
1)語法:
函數(shù)名(實參列表)
2)說明
函數(shù)名 —— 必須是已經(jīng)聲明過的函數(shù)
() —— 固定寫法
實參列表 —— 數(shù)據(jù)1, 數(shù)據(jù)2··· 給形參賦值
同一個函數(shù)可以調(diào)用多次
3)函數(shù)的調(diào)用過程(重要*********)
一、回到函數(shù)聲明的位置
二裸删、用實參給形參賦值 (傳參)要保證每一個形參都要有值
三八拱、執(zhí)行函數(shù)體
四、獲取返回值
五、回到函數(shù)調(diào)用的位置肌稻,接著往后執(zhí)行
函數(shù)的參數(shù)
1清蚀、位置參數(shù)、關鍵字參數(shù)
調(diào)用函數(shù)的時候 根據(jù)實參的寫法分為位置參數(shù)灯萍、關鍵字參數(shù)
- 位置參數(shù):讓實參的順序與形參一一對應轧铁,用逗號隔開
- 關鍵字參數(shù):以'形參名1 = 值1, 形參名2 = 值2····' 格式來確定實參
- 位置參數(shù)+關鍵字參數(shù):位置參數(shù)必須寫在關鍵字參數(shù)前
2旦棉、參數(shù)默認值
聲明函數(shù)的時候齿风,可以給形參賦默認值
有默認值的形參在函數(shù)調(diào)用的時候,可以不用給形參賦值
注意:聲明的時候绑洛,有默認值的參數(shù)必須放在最后救斑,當跳過有默認值的參數(shù)賦值時,必須使用關鍵字參數(shù)
def func2(a, b=12, c=19):
print(a, b, c)
# 調(diào)用函數(shù)只給a和c賦值真屯,b使用默認值
func2(13, c=23)
3脸候、參數(shù)的類型說明
python中類型只有說明的作用,沒有約束的作用绑蔫,有兩種方法:
1)參數(shù)賦默認值
2)參數(shù)名:類型
4运沦、不定長參數(shù) - 形參的參數(shù)不確定
聲明函數(shù)的時候,在形參前面加*星號配深,那么這個參數(shù)就變成不定長參數(shù)携添,
同時可以接收多個實參(將這個參數(shù)變成元祖)必須用位置實參數(shù)聲明函數(shù)的時候,在形參的前面加**兩個星號篓叶,那么這個參數(shù)也會變成不定長參數(shù)烈掠,
同時可以接收多個實參(將這個參數(shù)變成字典)必須用關鍵字實參數(shù),關鍵字是key
注意:定長參數(shù)必須在不定長參數(shù)前面
不帶星號的參數(shù)要放在帶星號參數(shù)的前面
練習: 練習:寫一個函數(shù)缸托,按指定方式計算多個數(shù)字的結(jié)果
operation('+', '23', '24') ——> 23 + 24
operation('-', '23', '24')
def operation(ex, *a):
if ex == '+':
num1 = 0
for x in range(len(a)):
num1 += x
print(num1)
elif ex == '*':
num1 = 1
for x in range(len(a)):
num1 *= x
練習:寫一個函數(shù)求多個數(shù)的和 既可以使用位置傳參左敌,又可以使用關鍵字傳參
def func1(*args, **kwargs):
"""
求多個數(shù)的和
:param args:不定長參數(shù) 位置參數(shù) 整型 元祖
:param kwargs: 不定長參數(shù) 關鍵字參數(shù) 字典
:return:
"""
sum1 = 0
print(sum(args))
for key in kwargs:
sum1 += kwargs[key]
print(sum1 + sum(args))
func1(2, 3, 4, a=2, b=3, c=4)
函數(shù)的返回值
1、什么是函數(shù)的返回值
返回值就是return關鍵字后面表達式的值俐镐,就是函數(shù)調(diào)用表達式的值
return
函數(shù)體中的關鍵字 只能出現(xiàn)在函數(shù)體里
作用:
- 結(jié)束函數(shù)
- 確定函數(shù)返回值
調(diào)用函數(shù):執(zhí)行函數(shù)體 獲取返回值
函數(shù)調(diào)用過程: 重要
一矫限、回到函數(shù)聲明的位置
二、用實參給形參賦值 (傳參)要保證每一個形參都要有值
三佩抹、執(zhí)行函數(shù)體
四奇唤、獲取返回值
執(zhí)行完函數(shù)體:函數(shù)體執(zhí)行完、執(zhí)行過程中遇到return
確定函數(shù)返回值:執(zhí)行函數(shù)的過程中有沒有遇到return匹摇,
如果遇到了,return后表達式的值就是函數(shù)的返回值
沒有遇到return甲葬,函數(shù)返回值就是None
五廊勃、回到函數(shù)調(diào)用的位置,接著往后執(zhí)行(這個時候函數(shù)調(diào)用表達式的值就是函數(shù)的返回值)
2、什么時候需要返回值
如果實現(xiàn)函數(shù)的功能坡垫,會產(chǎn)生新的數(shù)據(jù)梭灿,就把這個數(shù)據(jù)作為返回值
return 返回值1,返回值2
匿名函數(shù)
什么是匿名函數(shù)
匿名函數(shù)就是沒有名字的函數(shù)
1)語法:
lambda 參數(shù)列表:返回值
2)說明
lambda - 關鍵字
參數(shù)列表 - 相當于普通函數(shù)形參列表
: - 固定寫法
返回值 - 相當于普通函數(shù)函數(shù)體中的return 不能是賦值語句·
注意:
- 匿名函數(shù)本質(zhì)還是函數(shù),函數(shù)中的語法絕大多數(shù)是適用的
- 匿名函數(shù)能做的事情冰悠,普通函數(shù)都可以做堡妒。只是匿名函數(shù)簡潔
- 不支持通過類型名對參數(shù)類型說明
練習:匿名函數(shù)求兩個數(shù)的和
# 匿名函數(shù)是一個類型為function的值
fun1 = lambda a, b=1: a+b
print(fun1(1, 2))
print(fun1(a=1, b=2))
print(fun1(1))
函數(shù)中的變量
1.變量的作用域
指的是變量的使用范圍
全局變量、局部變量
2.全局變量
只要是沒有聲明在函數(shù)中的變量都是全局變量
全局變量的作用域是從變量聲明開始到整個py文件結(jié)束
3.局部變量
聲明在函數(shù)中的變量都是局部變量
局部變量的作用域就是從變量聲明到函數(shù)結(jié)束
注意:形參也是局部變量
當調(diào)用函數(shù)的時候溉卓,系統(tǒng)會自動在內(nèi)存的棧區(qū)間為這個函數(shù)開辟一個獨立的內(nèi)存區(qū)域
用來保存在函數(shù)中聲明的變量或者產(chǎn)生的數(shù)據(jù)皮迟。當函數(shù)調(diào)用結(jié)束后,這塊內(nèi)存區(qū)域會自動銷毀
4. global 和 nonlocal
global - 在函數(shù)中聲明一個全局變量 只能在函數(shù)中使用
global 變量名
變量名 = 值
nonlocal - 在局部的局部中修改一個局部變量的值
nonlocal 局部變量名
局部變量名 = 值
x1 = 100
def func4():
# x1 = 200 這個x1是局部變量
global x1 # 說明后面的x1是一個全局變量
x1 = 200
print('函數(shù)中', x1)
func4()
print('函數(shù)外', x1)
print('0-------------')
def func5():
x2 = 100
def func6():
# x2 = 200
nonlocal x2
x2 = 200
print('函數(shù)5的函數(shù)6中', x2)
func6()
print('函數(shù)5中', x2)
func5()
函數(shù)作為變量
1.函數(shù)作為變量
python中聲明函數(shù)其實就是聲明一個類型是function的變量
函數(shù)名就是變量名
所以普通變量能做的事情函數(shù)都可以做
2.一個變量可以給另一個變量賦值
def func1():
return 100
c = func1
c()
print(c())
func1 = 12.5
print(func1)
3.一個變量可以作為一個容器的元素
a = 10 #聲明一個變量桑寨,類型是整型
print(type(a))
# 聲明一個變量伏尼,類型是function
def func2():
print('這是函數(shù)2')
return 100
print(type(func2))
list1 = [a, func2, func2()]
print(list1)
print('0:', list1[0] // 3)
print('1:', list1[1]()) # print('1:', func2()) -> print('1:', 100)
練習:
list2 = []
for i in range(5):
def func(n):
return i * 2
list2.append(func)
list3 = []
for i in range(5):
list3.append(lambda x: x*i)
print(list3[0](2), list3[1](2), list3[2](2))
"""
list2 = []
i = 0 ~ 4
i = 0: func, list2 = [func]
i = 1: func, list2 = [func, func]
...
i = 4: list2 = [func,func,func,func,func]
"""
# list2[0](3), list2[1](3), list2[2](3)
# func, func, func
# None, None, None
# 0, 2, 3
# 8, 8, 8
print(list2)
print(list2[0](3), list2[1](3), list2[2](3))
4. 變量可以作為函數(shù)的參數(shù)
函數(shù)作為函數(shù)的參數(shù)(實參高階函數(shù))
def func1(fn, fn2):
# fn = func11
# fn2 = func12
fn() # func11(), None
print(fn2(3) / 4) # print(9/4)
def func11():
print('這是一個函數(shù)')
def func12(n):
# n = 3
return n**2
print(func1(func11, func12)) # print(None)
應用: sort函數(shù) (排序)
nums = [1, 23, 34, 32, 12]
nums.sort() # 從小到大排序
print(nums)
序列.sort函數(shù)中有個參數(shù)key,這個參數(shù)要求傳一個函數(shù)尉尾,并且函數(shù)有一個參數(shù)和一個返回值
參數(shù)就是序列中的元素爆阶,返回值就是排序比較的對象
all_stu = [
{'name': 'dd', 'age': 12, 'score': 32},
{'name': 'ad', 'age': 15, 'score': 41},
{'name': 'sd', 'age': 13, 'score': 36},
{'name': 'cd', 'age': 11, 'score': 72}
]
def compare(item):
return item['age']
all_stu.sort(key=compare)
all_stu.sort(key=lambda item: item['age'])
print(all_stu)
all_message = [
('張', 'python1902001'),
('李', 'python1902108'),
('王', 'python1902046')
]
all_message.sort(key=lambda item: item[1], reverse=True)
print(all_message)
all_message.sort(key=lambda item: item[1][-1])
print(all_message)
5.變量作為函數(shù)的返回值
將一個函數(shù)作為函數(shù)的返回值(返回值高階函數(shù))
def func1():
def temp(*nums):
return sum(nums)
return temp
print(func1()(1, 2, 3, 4))
迭代器 (iter)
1.什么是迭代器(iter)
是容器型數(shù)據(jù)類型(可以同時存儲多個數(shù)據(jù)),但是想要獲取沙咏、查看迭代器中元素的值
只能將元素取出來辨图,取出來的元素,在迭代器中就不存在了肢藐,去的時候在只能從前往后一個一個的取故河,不能跳著取
2.迭代器中的元素
迭代器只能通過類型轉(zhuǎn)換將其他容器轉(zhuǎn)換成迭代器,或者通過生成器生成
轉(zhuǎn)換 - 所有序列都可以轉(zhuǎn)換成迭代器窖壕。迭代器中的元素可以是任何類型的數(shù)據(jù)
3.獲取元素 -
迭代器獲取元素忧勿,無論以什么樣的方式獲取獲取后,這個元素在迭代器中就不存在了
- next(迭代器) - 獲取迭代器最上的數(shù)據(jù)
- 遍歷獲取每一個元素
# 1) next(迭代器) - 獲取迭代器最上的數(shù)據(jù)
iter2 = iter('hello')
print(next(iter2))
print(next(iter2))
print(next(iter2))
print(next(iter2))
print(next(iter2))
# print(next(iter2)) 錯誤 # StopIteration
# 2) 遍歷獲取每一個元素
iter3 = iter('hello')
for x in iter3:
print(x)
生成器
1.什么是生成器
生成器本質(zhì)是迭代器瞻讽,迭代器不一定是生成器
調(diào)用一個帶有yield關鍵字的函數(shù)就能得到一個生成器. yield只能在函數(shù)體里
def func1():
print('--')
return 100
yield
gen1 = func1()
print(gen1)
2.生成器的元素
生成器獲取元素的方式和迭代器一樣 next()和 遍歷
- 生成器元素的個數(shù):看執(zhí)行完生成器對應的函數(shù)會遇到幾次yield
- 元素的值:看yield后表達式的值
3.生成器產(chǎn)生數(shù)據(jù)的原理
當獲取生成器的元素的時候鸳吸,會執(zhí)行生成器對應的函數(shù),從開始執(zhí)行到y(tǒng)ield為止速勇,并且將yield后面的數(shù)據(jù)作為元素返回
并且記錄結(jié)束位置晌砾,下次再獲取元素的時候,從上次結(jié)束的位置接著往后執(zhí)行烦磁,直到遇到y(tǒng)ield养匈,并且將yield后面的數(shù)據(jù)作為元素返回
以此類推。
如果函數(shù)從開始到結(jié)束時都沒有遇到y(tǒng)ield都伪,就獲取不到元素呕乎。next會報錯 for循環(huán)會結(jié)束
def func2():
print('===')
yield 200
gen3 = func2()
print(next(gen3))
生成式
本質(zhì)還是生成器 只是寫法更簡潔
寫法:
語法1.
(表達式 for 變量 in 序列)
展開
def func():
for 變量 in 序列:
yield 表達式
func()
() - 固定寫法
表達式 - 除了賦值以外的任何語句,如數(shù)據(jù)陨晶、變量猬仁、運算表達式帝璧、函數(shù)調(diào)用表達式
一般和后面的變量有聯(lián)系
for in - for循環(huán)
語法2.
(表達式 for 變量 in 序列 if 條件語句)
展開
def func():
for 變量 in 序列:
if 條件語句:
yield 表達式