解包在英文里叫做 Unpacking,就是將容器里面的元素逐個(gè)取出來(防杠精:此處描述并不嚴(yán)謹(jǐn),因?yàn)槿萜髦械脑夭]有發(fā)生改變)放在其它地方,好比你老婆去菜市場(chǎng)買了一袋蘋果回來分別發(fā)給家里的每個(gè)成員,這個(gè)過程就是解包。
Python 中的解包是自動(dòng)完成的,例如:
如果列表中有3個(gè)元素,那么剛好可以分配給3個(gè)變量。除了列表對(duì)象可以解包之外,任何可迭代對(duì)象都支持解包,可迭代對(duì)象包括元組、字典、集合、字符串、生成器等實(shí)現(xiàn)了next方法的一切對(duì)象。
元組解包
字符串解包
字典解包
字典解包后,只會(huì)把字典的 key 取出來,value 則丟掉了。
你可能見過多變量賦值操作,例如:
本質(zhì)上也是自動(dòng)解包過程,等號(hào)右邊其實(shí)是一個(gè)元組對(duì)象 (1, 2),有時(shí)候我們代碼不小心多了一個(gè)逗號(hào) ,,就變成了元組對(duì)象
所以寫代碼的時(shí)候需要特別注意。在 Python 中,交換兩個(gè)變量非常方便,本質(zhì)上也是自動(dòng)解包過程。
如果在解包過程中,遇到左邊變量個(gè)數(shù)小于右邊可迭代對(duì)象中元素的個(gè)數(shù)時(shí)該怎么辦? 好比你們家有3口人,你老婆卻買了4個(gè)蘋果,怎么分配呢?
在 Python2 中,如果等號(hào)左邊變量的個(gè)數(shù)不等于右邊可迭代對(duì)象中元素的個(gè)數(shù),是不允許解包的。但在 Python3 可以這么做了。這個(gè)特性可以在 PEP 3132 中看到。
這種語法就是在某個(gè)變量面前加一個(gè)星號(hào),而且這個(gè)星號(hào)可以放在任意變量,每個(gè)變量都分配一個(gè)元素后,剩下的元素都分配給這個(gè)帶星號(hào)的變量
這種語法有什么好處呢?它使得你的代碼寫起來更簡潔,比如上面例子,在 Python2 中該怎么操作呢?思考3秒鐘,再看答案。
以上是表達(dá)式解包的一些操作,接下來介紹函數(shù)調(diào)用時(shí)的解包操作。函數(shù)調(diào)用時(shí),有時(shí)你可能會(huì)用到兩個(gè)符號(hào):星號(hào)和 雙星號(hào)*。
func 函數(shù)定義了三個(gè)位置參數(shù) a,b,c,調(diào)用該函數(shù)必須傳入三個(gè)參數(shù),除此之外,你也可以傳入包含有3個(gè)元素的可迭代對(duì)象,
函數(shù)被調(diào)用的時(shí)候,使用星號(hào) * 解包一個(gè)可迭代對(duì)象作為函數(shù)的參數(shù)。字典對(duì)象,可以使用兩個(gè)星號(hào),解包之后將作為關(guān)鍵字參數(shù)傳遞給函數(shù)
看到了嗎?和上面例子的區(qū)別是多了一個(gè)星號(hào),結(jié)果完全不一樣,原因是什么? 答案是** 符號(hào)作用的對(duì)象是字典對(duì)象,它會(huì)自動(dòng)解包成關(guān)鍵字參數(shù) key=value 的格式:
如果字典對(duì)象中的 key 不是 a,b,c,會(huì)出現(xiàn)什么情況?請(qǐng)讀者自行測(cè)試。
總結(jié)一下,一個(gè)星號(hào)可作用于所有的可迭代對(duì)象,稱為迭代器解包操作,作為位置參數(shù)傳遞給函數(shù),兩個(gè)星號(hào)只能作用于字典對(duì)象,稱之為字典解包操作,作為關(guān)鍵字參數(shù)傳遞給函數(shù)。使用 和 * 的解包的好處是能節(jié)省代碼量,使得代碼看起來更優(yōu)雅,不然你得這樣寫:
到這里,解包還沒介紹完,因?yàn)?Python3.5,也就是 PEP 448 對(duì)解包操作做了進(jìn)一步擴(kuò)展, 在 3.5 之前的版本,函數(shù)調(diào)用時(shí),一個(gè)函數(shù)中解包操作只允許一個(gè) 和 一個(gè)*。從 3.5 開始,在函數(shù)調(diào)用中,可以有任意多個(gè)解包操作,例如:
再來看看 python3.5以上版本
從 3.5 開始可以接受多個(gè)解包,于此同時(shí),解包操作除了用在函數(shù)調(diào)用,還可以作用在表達(dá)式中。
新的語法使得我們的代碼更加優(yōu)雅了,例如拼接兩個(gè)列表可以這樣:
可不可以直接用 + 操作呢?不行,因?yàn)?list 類型無法與 range 對(duì)象相加,你必須先將 list2 強(qiáng)制轉(zhuǎn)換為 list 對(duì)象才能做 +操作,這個(gè)留給讀者自行驗(yàn)證。
再來看一個(gè)例子:如何優(yōu)雅的合并兩個(gè)字典
在3.5之前的版本,你不得不寫更多的代碼:
到此,關(guān)于 Python 解包給你介紹完了,如果本文對(duì)你有收獲,請(qǐng)點(diǎn)贊、轉(zhuǎn)發(fā)支持。
最后給你總結(jié)一下:
自動(dòng)解包支持一切可迭代對(duì)象
- python3中,支持更高級(jí)的解包操作,用星號(hào)操作使得等號(hào)左邊的變量個(gè)數(shù)可以少于右邊迭代對(duì)象中元素的個(gè)數(shù)。
- 函數(shù)調(diào)用時(shí),可以用 或者 * 解包可迭代對(duì)象,作為參數(shù)傳遞
- python3.5,函數(shù)調(diào)用和表達(dá)式中可支持更多的解包操作。