前言
1、解包在英文里叫做 Unpacking,就是將容器里面的元素逐個取出來(防杠精:此處描述並不嚴謹,因為容器中的元素並沒有發生改變)放在其它地方。
2、舉例:
如果列表中有3個元素,那么剛好可以分配給3個變量。
除了列表對象可以解包之外,任何可迭代對象都支持解包;可迭代對象包括元組、字典、集合、字符串、生成器等實現了__next__方法的一切對象。
3、
1、概念
解包就是把一個容器拆開、分解,在Python中的解包是自動完成的。
變量數量 = 元素數量,會進行逐一賦值。
2、注意
(1)自動解包支持一切可迭代對象。
(2)python3中,支持更高級的解包操作,用星號操作使得等號左邊的變量個數可以少於右邊迭代對象中元素的個數。
(3)函數調用時,可以用*或者**解包可迭代對象,作為參數傳遞。
(4)python3.5,函數調用和表達式中可支持更多的解包操作。
3、實例
一個list是一個整體,想把list中每個元素當成個體剝離出來。
>>> name, age, date = ['Bob', 20, '2018-1-1'] >>> name 'Bob' >>> age 20 >>> date '2018-1-1' 2.可迭代對象都可以這樣做 # 列表 >>> a,b,c = ['a', 'b', 'c'] >>> a 'a' >>> a,b,c = enumerate(['a', 'b', 'c']) >>> a (0, 'a') # 元組 >>> a,b,c = ('a', 'b', 'c') >>> a 'a' # 字典 >>> a,b,c = {'a':1, 'b':2, 'c':3} >>> a 'a' >>> a,b,c = {'a':1, 'b':2, 'c':3}.items() >>> a ('a', 1) # 字符串 >>> a,b,c = 'abc' >>> a 'a' # 生成器 >>> a,b,c = (x + 1 for x in range(3)) >>> a 1
元組解包
字符串解包
字典解包
但是字典解包后,只會把字典的 key 取出來,value 則丟掉了。
1、你可能見過多變量賦值操作,例如:
本質上也是自動解包過程,等號右邊其實是一個元組對象 (1, 2),有時候我們代碼不小心多了一個逗號,就變成了元組對象
2、在 Python 中,交換兩個變量非常方便,本質上也是自動解包過程。
3、如果在解包過程中,遇到左邊變量個數小於右邊可迭代對象中元素的個數時該怎么辦? 好比你們家有3口人,你老婆卻買了4個蘋果,怎么分配呢?
在 Python2 中,如果等號左邊變量的個數不等於右邊可迭代對象中元素的個數,是不允許解包的。
4、但在 Python3 可以這么做了。這個特性可以在 PEP 3132 中看到。例如下面這塊代碼:
這種語法就是在某個變量面前加一個星號,而且這個星號可以放在任意變量,每個變量都分配一個元素后,剩下的元素都分配給這個帶星號的變量
5、這種語法有什么好處呢?它使得你的代碼寫起來更簡潔,比如上面例子,在 Python2 中該怎么操作呢?思考3秒鍾,再看答案。
6、以上是表達式解包的一些操作,接下來介紹函數調用時的解包操作。函數調用時,有時你可能會用到兩個符號:星號*和 雙星號**。
func 函數定義了三個位置參數 a,b,c,調用該函數必須傳入三個參數,除此之外,你也可以傳入包含有3個元素的可迭代對象,
函數被調用的時候,使用星號 * 解包一個可迭代對象作為函數的參數。字典對象,可以使用兩個星號,解包之后將作為關鍵字參數傳遞給函數
看到了嗎?和上面例子的區別是多了一個星號,結果完全不一樣,原因是什么? 答案是** 符號作用的對象是字典對象,它會自動解包成關鍵字參數 key=value 的格式:
如果字典對象中的 key 不是 a,b,c,會出現什么情況?請讀者自行測試。
總結一下,一個星號可作用於所有的可迭代對象,稱為迭代器解包操作,作為位置參數傳遞給函數,兩個星號只能作用於字典對象,稱之為字典解包操作,作為關鍵字參數傳遞給函數。使用 *和 ** 的解包的好處是能節省代碼量,使得代碼看起來更優雅,不然你得這樣寫:
到這里,解包還沒介紹完,因為 Python3.5,也就是 PEP 448 對解包操作做了進一步擴展, 在 3.5 之前的版本,函數調用時,一個函數中解包操作只允許一個* 和 一個**。從 3.5 開始,在函數調用中,可以有任意多個解包操作,例如:
再來看看 python3.5以上版本
從 3.5 開始可以接受多個解包,於此同時,解包操作除了用在函數調用,還可以作用在表達式中。
新的語法使得我們的代碼更加優雅了,例如拼接兩個列表可以這樣:
可不可以直接用 + 操作呢?不行,因為 list 類型無法與 range 對象相加,你必須先將 list2 強制轉換為 list 對象才能做 +操作,這個留給讀者自行驗證。
再來看一個例子:如何優雅的合並兩個字典
在3.5之前的版本,你不得不寫更多的代碼:
到此,關於 Python 解包給你介紹完了。
最后總結一下:
- 自動解包支持一切可迭代對象
- python3中,支持更高級的解包操作,用星號操作使得等號左邊的變量個數可以少於右邊迭代對象中元素的個數。
- 函數調用時,可以用 * 或者 ** 解包可迭代對象,作為參數傳遞
- python3.5,函數調用和表達式中可支持更多的解包操作。