01 recode
1. 函數(shù)的聲明(聲明函數(shù)的時候不會執(zhí)行函數(shù)體)
def 函數(shù)名(參數(shù)列表):
函數(shù)的說明文檔 ---> 放在引號注釋里迁筛,注釋說明函數(shù)功能
函數(shù)體
參數(shù)列表中的闡述可以進(jìn)行參數(shù)類型說明(只是進(jìn)行說明粟判,沒有強(qiáng)制限制類型呼寸,但一般不要違反)可以通過 參數(shù)名: 類型名 來指定參數(shù)的類型逼友,也可以通過設(shè)置默認(rèn)值來說明參數(shù)的類型
def 函數(shù)名(參數(shù)1: int, 參數(shù)2=[])
-
說明類型的好處:
a. 傳什么類型參數(shù)一目了然
b. 實(shí)現(xiàn)函數(shù)體時有相應(yīng)的代碼提示 return 也可以進(jìn)行說明
def 函數(shù)名(參數(shù)1: int, 參數(shù)2=[]) ->返回值類型:
2. 函數(shù)的調(diào)用
- 格式:
函數(shù)名(實(shí)參列表)
-
調(diào)用過程:
第一步:回到函數(shù)聲明的位置
第二步:用實(shí)參給形參賦值 ---> 傳參(保證每個參數(shù)都要有值)
第三步:執(zhí)行函數(shù)體
第四步:確定返回值 ---> 將函數(shù)調(diào)動表達(dá)式設(shè)置為返回值
第五步:回到函數(shù)調(diào)用的位置汽纠,接著往后執(zhí)行
3. 函數(shù)的參數(shù)
-
分類
位置參數(shù)
關(guān)鍵字參數(shù)
參數(shù)的默認(rèn)值 ---> 有默認(rèn)值的參數(shù)要放在沒有默認(rèn)值的參數(shù)后面
不定長參數(shù) ---> 在參數(shù)前面加 * 下面有補(bǔ)充
def func1(a: int, b=[]):
"""
把參數(shù)a 添加到列表b中
:param a:
:param b:
:return:
"""
b.append(a)
return b
print(func1(1, [1, 2, 3])) #[1, 2, 3, 1]
-
補(bǔ)充:不定長參數(shù)(面試題)
-
說說*args, **kwargs之間的區(qū)別
args 就是參數(shù)名前加一顆, 將位置參數(shù)作為元組的元素秒啦,參數(shù)就是一個元組
kwargs 就是參數(shù)名前加兩顆,必須以關(guān)鍵字的方式傳參,然后將關(guān)鍵字參數(shù)轉(zhuǎn)換為字典
注意:經(jīng)常將 *args 和 **kwargs放在一起組合使用鸥鹉,但是使用的時候蛮穿,兩顆星的要放在后面?zhèn)鲄?shù)的時候,關(guān)鍵字參數(shù)也要放在位置參數(shù)后面
def func2(*args, **kwargs):
print(args, kwargs, sep = "\n")
func2(1, 2, 3, 4, {"b": 1}, a = 12) # (1, 2, 3, 4, {"b": 1}), {"a": 12}
func2(1, 2, 3) # (1, 2, 3) {}
func2(a = 1, b = 2, c = 3) # () {"a": 1, "b": 2, "c": 3}
4. 返回值
python中所有的函數(shù)都有返回值毁渗,默認(rèn)的返回值是None践磅,如果遇到return,函數(shù)的返回值就是return后面的值
返回值就是函數(shù)調(diào)用表達(dá)式的值
調(diào)用函數(shù)的目的:a. 執(zhí)行函數(shù)體 b. 獲取返回值
函數(shù)調(diào)用表達(dá)式: fun_x(實(shí)參)
-
return的作用: a. 返回返回值 b. 結(jié)束函數(shù)(函數(shù)中遇到return就結(jié)束函數(shù))
02 匿名函數(shù)
- 普通函數(shù):
def 函數(shù)名(參數(shù)列表):
函數(shù)體
- 匿名函數(shù):
函數(shù)名(變量名) = lambda 參數(shù)列表:返回值
- 說明:
a. 函數(shù)名 ---> 變量名
b. lambda ---> 聲明匿名函數(shù)的關(guān)鍵字
c. 參數(shù)列表 ---> 由多個參數(shù)組成灸异,至少有一個
d. 返回值 ---> 相當(dāng)于只有一個return語句的函數(shù)體
匿名函數(shù)的調(diào)用和普通函數(shù)一樣,支持位置參數(shù)府适, 關(guān)鍵字參數(shù), 參數(shù)也可以設(shè)置默認(rèn)值, 支持不定參數(shù)
- 特點(diǎn):
直接將函數(shù)的聲明作為一個值存到一個變量
將函數(shù)聲明賦給一個變量
# 求兩數(shù)之和
sum_num = lambda x, y: x + y
print(sum_num(10, 20)) # 30
# 求1+2+……n的和
sum_nums = lambda n: sum(range(n+1))
print(sum_nums(100)) # 5050
sum1 = lambda *num:sum(num)
print(sum1(1, 2, 3)) # 6
# 練習(xí):讀程序
funcs = []
for item in range(1, 5): # 執(zhí)行完循環(huán) funcs = [lambda x: x * item, lambda x: x * item, lambda x: x * item, lambda x: x * item]
funcs.append(lambda x: x * item) # 循環(huán)結(jié)束后item = 4
print(funcs[0](2)) # 8
print(funcs[1](2)) # 8
03 變量的作用域
- 變量的作用域
變量的作用域指的是變量能夠使用的范圍
- 變量的作用域
- 全局變量
全局變量:聲明在函數(shù)和類的外面的變量都是全局變量肺樟;
作用域:作用域是從聲明開始到整個Py文件結(jié)束都可以使用
- 全局變量
-
全局變量 a 檐春、 b 、 x 都是全局變量么伯,只有涉及函數(shù)和類里面的變量才是局部的
a = 10
print("=====")
for x in range(2):
b = 5
print(a) # 10 10
if True:
print(a) # 10
print(a) # 10
print("=====")
- 局部變量
聲明在函數(shù)和類中的變量都是局部變量疟暖,聲明在函數(shù)的局部變量,作用域從聲明開始到整個函數(shù)結(jié)束田柔,只能在函數(shù)局部使用
- 局部變量
def func1():
aa = 100
bb = 200
# print(aa, bb) 報錯誓篱,aa和bb沒有被定義
- global關(guān)鍵字
只能在函數(shù)里用:在函數(shù)中聲明一個全局變量
- global關(guān)鍵字
name = "abc"
def func2():
global name # 說明當(dāng)前函數(shù)中使用的name是全局變量的name
print(name)
name = "aaa"
print(name)
func2() # "abc" "aaa"
print(name) # "aaa"
- nonlocal 關(guān)鍵字
def func5():
a1 = 500
# nonlocal a1 # 就算聲明a1非局部的也不能在函數(shù)外使用,依舊是局限于函數(shù)內(nèi)部的
# global a1 # 就算在函數(shù)內(nèi)聲明a1為全局變量凯楔,但是只要函數(shù)外沒有a1被聲明窜骄,a1也是函數(shù)內(nèi)的
def func6():
nonlocal a1 # 讓a1不僅僅作用域在func6(),也可以作用于上一級的函數(shù)
print(a1)
a1 = 600
print(a1)
func6()
print(a1)
func5() # 500 600 600
04 函數(shù)作為變量
聲明函數(shù)就是聲明一個類型是function的變量摆屯,函數(shù)名是指就是變量名
def func1():
print("========")
print(type(func1)) # Class 'function'
# print(func1) # 打印出 function func1 at oxoo6155d0 打印出func1的被存于oxoo6155d0
- 變量能給其他變量賦值
a = 10 # 普通變量賦值
b = a
print(b * 10) # 100
list1 = [1, 2]
list2 = list1[:]
print(list2*2) # [1, 2, 1, 2]
# 函數(shù)給變量賦值
def func2():
print("我是函數(shù)")
x = func2 # 將func2 賦值給x
x() # "我是函數(shù)"
print(type(x)) # class "function"
func3 = lambda x: print(x) # 將func3賦值給y
y = func3
y(2) # 2
- 函數(shù)作為列表的元素
a = 10
list4 = [1, a]
print(list4, list4[1] + 100) # [1, 10] 110
def func10():
print("我是函數(shù)")
return 10
print("----------")
list5 = [1, func10, func10()] # list5[2] 首先會調(diào)用函數(shù)打印邻遏,之后將返回值存在列表中
print(list5) # [1, func10, 10]
print("========================")
print(list5[1]()) # 調(diào)用函數(shù)執(zhí)行打印 "我是函數(shù)"糠亩,然后打印出函數(shù)的返回值 10
- 將函數(shù)作為參數(shù)
print("==--==--==--==--==--==--")
a = 10
def func_a(n): # 往函數(shù)中傳普通變量
print(n)
func_a(a) # 10
# 給函數(shù)傳函數(shù)
def func_b(n):
# n = func_c
n() # 執(zhí)行 func_c(),打印出 "hello python"
def func_c():
print("hello python")
func_b(func_c) # "hello python"
-
應(yīng)用:sort的使用
列表.sort(key=None, reverse=False)
使用sort時准验,可以給key賦一個函數(shù)變量來規(guī)定函數(shù)用什么標(biāo)準(zhǔn)來排序,這兒的函數(shù)變量要求要有一個參數(shù)和一個返回值赎线,參數(shù)代表列表中的元素,返回值代表按照那個標(biāo)準(zhǔn)排序
list1 = [1, 2, 55, 33] # 列表中可以直接排序
list1.sort()
print(list1) # [1, 2, 33, 55]
list2 = [{"name": "張三", "age": 20, "grades": 90}, # 列表中有多個元素用key排序
{"name": "李四", "age": 18, "grades": 99},
{"name": "王二麻子", "age": 32, "grades": 77}]
def key_age(item):
return item["age"] # [{"name": "李四", "age": 18, "grades": 99}, {"name": "張三", "age": 20, "grades": 90}, {"name": "王二麻子", "age": 32, "grades": 77}]
# list2.sort(key=lambda item: item["age"])
list2.sort(key=key_age) #根據(jù)年齡排序
print(list2)
# 讓list3以第二個元素倒序排列
# method one
list3 = [(10, 2), ("c", 23), (33, 44)]
def key_2(item):
return item[1]
list3.sort(key=key_2, reverse=True)
print(list3) # # [(33, 44), (23, "c"), (10, 2)]
# method two
list3 = [(10, 2), ("c", 23), (33, 44)]
list3.sort(key=lambda item: item[1], reverse=True)
print(list3)
-
- 將函數(shù)作為返回值
根據(jù)運(yùn)算符糊饱,返回運(yùn)算符對應(yīng)的功能 功能對應(yīng)的就是函數(shù)
def operation(operator: str):
if operator == "+":
def func1(*args, **kwargs): # func1 相加功能
"""
求和功能
:param args: (1, 2)
:param kwargs: {"a": 3, "b", 4}
:return:
"""
sum1 = 0
for item in args:
sum1 += item
for keys in kwargs:
sum1 += kwargs[keys]
return sum1
return func1
elif operator == "*":
def func2(*args, **kwargs): # func2 相乘功能
"""
xiang功能
:param args: (1, 2)
:param kwargs: {"a": 3, "b", 4}
:return:
"""
sum1 = 1
for item in args:
sum1 *= item
for keys in kwargs:
sum1 *= kwargs[keys]
return sum1
return func2
f1 = operation("+") # f1 = func1,f1就是具有兩個不定長參數(shù)的有求和功能的函數(shù)
re = f1(1, 2, a=3, b=4)
print(re) # 10
# print(operation("+")(1, 2, a=3, b=4))
f2 = operation("*") # f2 =func2
re = f2(1, 2, a=3, b=4)
print(re) # 24
# print(operation("*")(1, 2, a=3, b=4))
05 函數(shù)的調(diào)用
- 補(bǔ)充: python中的函數(shù)可以有多個返回值
求多個數(shù)的和以及平均值
def sum_num(*nums):
sum1 = sum(nums)
average = sum1 / len(nums)
return sum1, average # 同時返回和垂寥、平均值
a, b = sum_num(2, 35, 6, 33, 76)
num = sum_num(2, 35, 6, 33, 76) # 返回的num為一個元組
print(a, b) # 152 30.4
print(num[0], num[1], num) # 152 30.4 (152, 30.4)
-
- 函數(shù)的調(diào)用過程是一個壓棧的過程
每次調(diào)用函數(shù)的時候,系統(tǒng)都會在內(nèi)存中(棧)開辟空間來存儲函數(shù)執(zhí)行過程中產(chǎn)生的數(shù)據(jù)(形參另锋、聲明的變量),當(dāng)函數(shù)調(diào)用完成后滞项,這塊內(nèi)存會自動銷毀棧內(nèi)存特點(diǎn):申請和釋放由系統(tǒng)完成
06 遞歸函數(shù)了解一哈
- 什么是遞歸函數(shù)(會導(dǎo)致內(nèi)存在一段時間猛增猛減,消耗cpu資源)遞歸函數(shù):函數(shù)中調(diào)用函數(shù)本身夭坪,這樣的函數(shù)就是遞歸函數(shù)(自己調(diào)用自己)
循環(huán)能做的事情文判,遞歸都可以做,但是實(shí)際上循環(huán)能解決的事情室梅,絕對不選遞歸
def func1():
print("===")
func1()
# func1() 達(dá)到最大遞歸次數(shù)戏仓,內(nèi)存不夠 maximum recursion depth exceeded while calling a Python object
-
- 怎么寫遞歸函數(shù)
第一步 確定臨界值(循環(huán)結(jié)束的條件),讓函數(shù)結(jié)束
第二步 找關(guān)系亡鼠,假設(shè)函數(shù)功能已經(jīng)實(shí)現(xiàn)赏殃,找f(n)和f(n-1)的關(guān)系
第三步 根據(jù)關(guān)系,用f(n-1)實(shí)現(xiàn)f(n)的功能
寫遞歸函數(shù)间涵,實(shí)現(xiàn)1+2+3+...n
def ey_sum(n):
# 1. 找臨界值
if n == 1:
return 1
# 2. 找關(guān)系
# ey_sum(n) = 1+2+3+……n
# ey_sum(n-1) = 1+2+3+……n-1
# ey_sum(n) = ey_sum(n-1) + n
# 3. 用f(n-1)實(shí)現(xiàn)f(n)功能
return ey_sum(n-1) + n
print(ey_sum(5)) # 15
- 調(diào)用過程:
ey_sum(5) return ey_sum(4) + 5 1 + 2 + 3 + 4 + 5
ey_sum(4) return ey_sum(3) + 4 1 + 2 + 3 + 4
ey_sum(3) return ey_sum(2) + 3 1 + 2 + 3
ey_sum(2) return ey_sum(1) + 2 1 + 2
ey_sum(1) return 1
用遞歸實(shí)現(xiàn)以下功能
n = 3
打印
***
**
*
def ey_star(n):
if n == 1:
print("*")
return
print("*"*n)
ey_star(n - 1)
ey_star(5) # *****
# ****
# ***
""" # **
n = 3 # *
打印
*
**
***
"""
def ey_print(n):
if n == 1:
print("*")
return
ey_print(n - 1)
print(n*"*")
ey_print(5) # *
# **
# ***
# ****
# *****