函數傳參
不可變傳複製,可變傳指針地址
一類不可以改變:整型、浮點型、字符串、Tuple。傳遞不可變類型,傳遞副本給函數,函數內操作不影響原始值
一類可以改變,列表 字典表。傳遞可變類型,傳遞地址引用,函數內操作可能影響原始值。如果不想改變可以傳遞副本。
參數匹配
- 參數匹配:默認位置匹配
- 參數匹配:順序打亂,按名稱匹配
- 參數匹配:有默認值可省略傳值
def func1(a,b,c):
print(a,b,c)
func1(1,2,3) #1 2 3
def func2(a, b, c):
print(a,b,c)
func2(c=1,b=2,a=3) # 3 2 1
def func3(a,b=2,c=3):
print(a,b,c)
func3(5) #5 2 3
參數的收集和分配(裝包和解包)
解包
a = (1, 2, 3, 4, 5, 6)
b = [2, 3, 4, 5, 5, 6]
c = {"name": 'zhang', "age": 2}
print(*a) #1 2 3 4 5 6
print(*b) #2 3 4 5 5 6
print(*c) #name age
一個星號*的作用
裝包
形參前面的星號將提供的所有值都放在一個元組tuple中,也就是將這些值都收集起來
def avg1(*scores): # 沒有做除數爲零的異常處理
return sum(scores) // len(scores)
print(avg1(90,100,80))
def avg2(score, *scores): # 函數定義時要求至少一個數字,避免除數爲零
return (score + sum(scores)) // (1 + len(scores))
print(avg2(0))
def avg3(*scores):
print(type(scores)) # <class 'tuple'>
if scores == (): # 根據可以看出,參數被收集爲元組
return
return sum(scores) // len(scores)
print(avg3())
混合參數
與賦值一樣,帶星號的參數也可以放在其他位置(而不是最後),但不同的是,在這種情況下需要做些額外的工作:使用關鍵字來指定後續參數
def fun1(x,*y,z):
print(x,y,z)
fun1(1,2,3,4,5,z=6) # 1 (2, 3, 4, 5) 6
def fun2(x,*y):
print(x,y)
fun2(1,2,3,4,5,6) # 1 (2, 3, 4, 5, 6)
兩個星號**收集參數
Python 中函數參數帶**的話,將會收集關鍵字參數到一個字典中;
- 如果傳遞整個list,形參與實參都需要*
>>> def fun(x,y,z=3,*pospar,**keypar):
... print(x,y,z)
... print(pospar)
... print(keypar)
...
>>> fun(1,2,4,4,5,6,a = 11,b = 12,c = 13)
1 2 4
(4, 5, 6)
{'a': 11, 'b': 12, 'c': 13}
>>> fun(1,2)
1 2 3
()
{}
>>>fun(1,2,4)
1 2 4
()
{}
如果一個一個傳遞值,形參用**
如果整體傳遞值對,形參與實參都用**即先解包再裝包
def display(**employee):
print(employee)
display(name="huang",age="23",job="Dev")
emp = {"name":"huang","age":"23","job":"Dev"}
display(**emp)
注意
在傳入參數時,可變參數(*)之前不能指定參數名
def myfun(a, *b):
print(a)
print(b)
myfun(a=1,2,3,4)
myfun(a=1,2,3,4)
^
SyntaxError: positional argument follows keyword argument
2.函數傳入實參時,可變參數(*)之後的參數必須指定參數名,否則就會被歸到可變參數之中
def myfun(a, *b, c=None):
print(a)
print(b)
print(c)
myfun(1,2,3,c=4)
1
(2, 3)
4
3.一個函數想要使用時必須明確指定參數名,可以將所有參數都放在可變參數之後
def myfun(*, a, b):
print(a)
print(b)
myfun(a=1, b=2)
1
2
4.關鍵字參數都只能作爲最後一個參數,前面的參數按照位置賦值還是名稱賦值都可以
def myfun(a, *b, c, **d):
print(a)
print(b)
print(c)
print(d)
myfun(1, 2, w=6, c=3, d=4, e=5) # 記住可變參數(*)之前不能指定參數名
1
(2,)
3
{'w': 6, 'd': 4, 'e': 5}
Lambda表達式
什麼是Lambad表達式
簡單理解:一個匿名函數,省略了定義函數時def 名稱 括號 冒號 return
lambda用來編寫簡單的函數,而def用來處理更強大的任務。
下面一個例子:
def holle(name):
print(name)
holle("普通例子")
f = lambda name : print(name)
f('lambda表達式例子')
f1 = lambda x, y : print(x+y)
f1([1,2,3],[2,3,4])
# 直接傳參
(lambda x, y : print(x+y))([1,2,3],[2,3,4])
lambda用來編寫跳轉表(jump table)行爲的列表或者字典
L = [lambda x: x+2, lambda x: x*2, lambda x: x**2]
print "L=", L[0](1), L[1](2), L[2](3)
#L = 3 4 9
D = {"d1": lambda x: x**1, "d2": lambda x: x**2, "d3": lambda x: x**3 }
print "D=", D["d1"](2), D["d2"](2), D["d3"](2)
使用lambda表達式,簡潔
while True:
name = input("請輸入您的名字:\n")
if name == 'stop':
break
language = input('請選擇語言:\n c=>中文\n e=>英文\n j=>日語')
if language == "c":
action = lambda name : print("你好", name)
elif language == "e":
action = lambda name : print("holle", name )
else:
action = lambda name : print("nihao", name)
action(name) # action統一接收執行內容,但是此時函數並沒有執行