Python給函式傳遞不定個數的引數

2021-08-28 01:14:25 字數 4300 閱讀 7073

在python中常常看到有這樣的函式,它們的入口引數的個數是不定的。比如有如下**

in: print zip([1, 2],[3, 4])

out: [(1, 3), (2, 4)]

in: print zip([1, 2],[3, 4],[5, 6])

out: [(1, 3, 5), (2, 4, 6)]

其中zip是python自帶的乙個函式,其作用麼,相信聰明的你已經看出來了。那如果有一天我們也要寫乙個能接受任意輸入個數的python函式,該如何實現呢?

今天我就遇到這個問題,然後花了一點時間解決了——答案是,借助*這個符號。雖然這是個很基礎的問題,網上資料很多,但還是想自己總結一下。

我們不妨先定義乙個灰常簡單的函式——實現兩個整數相加

def add_2_int(a1, a2):

return a1+a2

一目了然,這就好比剛學程式設計時的print "hello world!"

不滿足於此的我們,總想搞個大新聞——比如

實現多個整數的相加,但,事先不知道有幾個整數。

這時我們就需要再學習乙個——借助萬能的*,來改寫原函式:

def add_int(*a):

s = 0

for e in a:

s += e    return s

我們先不管函式是怎麼定義的、*a是什麼含義,我們先看下怎麼呼叫這個函式

in: print add_int(1, 2)

out: 3 in: print add_int(1, 2, 3)

out: 6

無論輸入幾個整數,都能求和,可見,這個函式已經能實現我們想要的功能了。

回過頭看,這裡呼叫add_int時輸入引數是三個:1,2,3,但給add_int定義的輸入是*a,那*的作用到底是什麼呢?其實就是在呼叫函式時,把輸入的三個引數1,2,3打包成乙個元組(tuple),即打包成(1,2,3)a這個引數,為了證明這點,我們不妨在函式中間加乙個print語句

def add_int(*a):

s = 0

print "input a is: ", a    for e in a:

s += e    return s

呼叫函式並看下輸出:

in: print add_int(1, 2, 3)

out: input a is:  (1, 2, 3)     6

確實若我們所料。

這時我們腦洞開始變大了,如果我輸入不是三個1,2,3,而是本身是乙個列表[1,2,3],會不會也能實現求和呢?比如有如下**

a_list = [1, 2, 3]print add_int(a_list)
啊哦,報錯了:unsupported operand type(s) for +=: 'int' and 'list',說list不能跟int相加。我們分析一下,按照剛剛的理論,這裡呼叫add_int時,只給了乙個引數a_list,於是*a會將a_list打包成(a_list, )a,當我們執行for e in a語句時,得到的是a裡面的每個元素,也就是a_list,而不是a_list裡面的元素,所以顯然無法得到想要的結果。

既然上面報錯了,那我們索性將錯就錯,設計乙個函式

實現任意多個list的『相加』——對於list而言+就是連線

我們只需修改函式add_int中用於存放累加結果的變數s即可,即:

def add_list(*a):

s = # 因為要返回list,所以s的初始值是而不是0

for e in a:

s += e    return s

比如我們要連線三個list[1,2],[3,4],[5,6],只需呼叫add_list([1, 2],[3, 4],[5, 6])即可得到[1, 2, 3, 4, 5, 6]

注意,上面我們說來說去,都是在函式定義階段使用*來打包(繫鈴),使得函式能接受任意多的入口引數個數。現在遇到乙個新問題:

給定兩個整數求和函式(即上面的add_2_int(a1, a2)),現在有乙個元組a_tuple = (1, 2),求1+2

暫時忘卻剛說到的*,為了解決這個問題,一般我們會逐個取出a_tuple裡的1,2,然後再呼叫函式,比如add_2_int(a_tuple[0], a_tuple[1])。有沒有更簡潔的方法呢?比如我們能否用某種手段使得輸入的a_tuple自動拆開(解鈴)成兩個引數1, 2再輸入函式呢?

答案是肯定的——還是用*,寫成add_2_int(*a_tuple),注意,現在是函式呼叫階段,這裡*的作用跟定義函式時恰恰相反,是將a_tuple(1,2)拆開成1, 2兩個引數輸入函式,對應函式的兩個入口引數a1, a2(擴充套件一下,這種函式的引數傳遞方式在python中叫按位置傳遞,還有按關鍵字傳遞的方法,本文就不細說了)

其實上面這個問題的想法**很樸素——既然*可以在函式定義時把入口引數『打包』成tuple型別,那我在函式呼叫時,也可以將tuple型別的變數『解壓』成乙個乙個的入口引數。那麼問題就來了,延續上述問題,我把問題變成:

給定add_2_int(a1, a2),現在有乙個列表a_list = [3, 4],乙個集合a_set = set([6, 5]),求3+45+6

不怕不怕,我們發現在解鈴階段(即函式呼叫階段),*不光能拆開tuple型別,包括set,list等通通可以,也就是通通可以這樣呼叫函式:add_2_int(*a_list),add_2_int(*a_set)

如果你腦洞再開啟一點,之前我們用*定義了add_int(*a)函式,現在有a_list=[1,2,3],那麼我們呼叫add_int(*a_list)會產生什麼效果呢?

本文簡單實驗了一下*在python函式中的作用,主要是區分函式定義和函式呼叫兩個階段,我把它稱作繫鈴和解鈴。

如果本文能對你編寫python函式有所幫助,也不枉鄙人熬夜啦善莫大焉~

給函式傳遞不定個數的引數

收藏參考 在python中常常看到有這樣的函式,它們的入口引數的個數是不定的。比如有如下 in print zip 1,2 3,4 out 1,3 2,4 in print zip 1,2 3,4 5,6 out 1,3,5 2,4,6 其中zip是python自帶的乙個函式,其作用麼,相信聰明的你...

C 傳遞不定參函式

定義不定引數函式,要用到下面這些巨集 c語言裡編寫不定引數函式的形式是這樣的 include int sum int cnt,定義不定引數函式,要用到下面這些巨集 typedef char va list define intsizeof n sizeof n sizeof int 1 sizeof...

python 給函式傳遞任意數量的實參

1.在預先不知道有多少個實參的情況下。可以使用如下操作,允許函式從呼叫語句中收集任意數量的實參。def function name test print test function name 1 function name 1 2 3 輸出結果 1 1 2 3 形參 test讓python 建立乙個...