參數的拆解與集成
清單的拆解
還記得我們使用過星號 *
來進行 unpack 的動作嗎?
其實在 Python 中,*
可以提供函式完成一些更進階的功能,我們再次考慮剛剛寫的加法函式:
def add(a,b,c,d):
return a+b+c+d
如果今天我們要對一個四元素的清單中的元素套用這個加法函式,我們可以透過綴星運算式來完成:
lst = [1,2,3,4]
print(add(*lst))
*lst
會執行 unpacking (拆解) 的動作,他會將 lst
拆解成四個整數 1, 2, 3 和 4,所以下面三個寫法是等價的:
add(*lst)
add(lst[1],lst[2],lst[3],lst[4])
add(1,2,3,4)
總而言之,*
會將一個有序群集拆解為該群集的元素後再呼叫函式。
清單的集成
綴星運算式不一定用在呼叫的時候,我們也可以在函式定義的地方使用他。
如果今天我們要撰寫三個數或四個數的加法:
def add(a,b):
return a+b
def add3(a,b,c):
return a+b+c+d
def add4(a,b,c,d):
return a+b+c+d
這麼做有幾個壞處,我們不能使用同一個函式名稱 add
來處理所有的 case。這在別的語言之中有 overload (多載) 來解決了,但 Python 中沒有這種機制,所以,我們必須對每一種數量的加法都寫一個新的函式,那實在是太麻煩了.
多載(overload) 指多個同名的函式可以同時存在,只要他們的參數數量或是型態不同。
我們可以考慮利用清單:
def add(lst):
return sum(lst)
這樣做已經相當不錯了,但是當呼叫的時候還是要先建立一個清單才能運算,如 add([1,2,3,4])
,我們想要能夠更直接的呼叫 add(1,2,3,4)
,只要這樣做:
def add(*lst):
return sum(lst)
位在參數列的 *lst
會將呼叫該函式所傳進來的所有元素組成一個元組,所以傳進來的四個整數 1, 2, 3, 4 將會被收集成元組 (1,2,3,4)
。有了這個技巧,我們能夠允許任意個資料輸入,最終我們會將之集成一個元組處理。
字典的拆解
對於字典類的群集,我們可以使用雙星號 **
的綴星運算式來拆解,這會讓函式以關鍵字的方式呼叫:
def power(base, exp):
return base ** exp
dic = {'base':2, 'exp':3}
print(power(**dic))
上例中的 **
(不是次方的雙星號) 會將 dic
拆解成 base=2
和 exp=3
,所以下面兩個寫法等價:
power(**dic)
power(base=2,exp=3)
字典的集成
而在定義函式上,也能允許任意數量資料輸入:
def power(**dic):
return dic['base'] ** dic['exp']
print(power(base=2, exp=3))
Python 會將呼叫函式的關鍵字輸入集成一個字典,也就是 base=2
和 exp=3
會因為 **
的使用而形成字典 {'base':2,'exp':3}
。