解包在英文裡叫做 unpacking,就是將容器裡面的元素逐個取出來(防槓精:此處描述並不嚴謹,因為容器中的元素並沒有發生改變)放在其它地方,好比你老婆去菜市場買了一袋蘋果回來分別發給家裡的每個成員,這個過程就是解包。python 中的解包是自動完成的,例如:
>>> a, b, c = [1,2,3]
>>> a
1>>> b
2>>> c
3
如果列表中有3個元素,那麼剛好可以分配給3個變數。除了列表物件可以解包之外,任何可迭代物件都支援解包,可迭代物件包括元組、字典、集合、字串、生成器等實現了__next__方法的一切物件。
元組解包
>>> a,b,c = (1,2,3)
>>> a
1>>> b
2>>> c
3
字串解包
>>> a,b,c = "abc"
>>> a
'a'>>> b
'b'>>> c
'c'
字典解包
>>> a,b,c =
>>> a
'a'>>> b
'b'>>> c
'c'
字典解包後,只會把字典的 key 取出來,value 則丟掉了。
你可能見過多變數賦值操作,例如:
>>> a, b = 1, 2
>>> a
1>>> b
2
本質上也是自動解包過程,等號右邊其實是乙個元組物件 (1, 2),有時候我們**不小心多了乙個逗號 ,,就變成了元組物件
>>> a = 1,
>>> a
(1,)
----------
>>> a = 1
>>> a
1
所以寫**的時候需要特別注意。在 python 中,交換兩個變數非常方便,本質上也是自動解包過程。
>>> a, b = 1, 2
>>> a, b = b, a
>>> a
2>>> b
1
如果在解包過程中,遇到左邊變數個數小於右邊可迭代物件中元素的個數時該怎麼辦? 好比你們家有3口人,你老婆卻買了4個蘋果,怎麼分配呢?
在 python2 中,如果等號左邊變數的個數不等於右邊可迭代物件中元素的個數,是不允許解包的。但在 python3 可以這麼做了。這個特性可以在 pep 3132 中看到。
>>> a, b, *c = [1,2,3,4]
>>> a
1>>> b
2>>> c
[3, 4]
>>>
這種語法就是在某個變數面前加乙個星號,而且這個星號可以放在任意變數,每個變數都分配乙個元素後,剩下的元素都分配給這個帶星號的變數
>>> a, *b, c = [1,2,3,4]
>>> a
1>>> b
[2, 3]
>>> c
4
這種語法有什麼好處呢?它使得你的**寫起來更簡潔,比如上面例子,在 python2 中該怎麼操作呢?思考3秒鐘,再看答案。
>>> n = [1,2,3,4]
# 使用切片操作
>>> a, b, c = n[0], n[1:-1], n[-1]
>>> a
1>>> b
[2, 3]
>>> c
4
以上是表示式解包的一些操作,接下來介紹函式呼叫時的解包操作。函式呼叫時,有時你可能會用到兩個符號:星號和 雙星號*。
>>> def func(a,b,c):
... print(a,b,c)
...>>> func(1,2,3)
1 2 3
func 函式定義了三個位置引數 a,b,c,呼叫該函式必須傳入三個引數,除此之外,你也可以傳入包含有3個元素的可迭代物件,
>>> func(*[1,2,3])
1 2 3
>>> func(*(1,2,3))
1 2 3
>>> func(*"abc")
a b c
>>> func(*)
a b c
函式被呼叫的時候,使用星號 * 解包乙個可迭代物件作為函式的引數。字典物件,可以使用兩個星號,解包之後將作為關鍵字引數傳遞給函式
>>> func(**)
1 2 3
看到了嗎?和上面例子的區別是多了乙個星號,結果完全不一樣,原因是什麼? 答案是** 符號作用的物件是字典物件,它會自動解包成關鍵字引數 key=value 的格式:
>>> func(a=1,b=2,c=3)
1 2 3
如果字典物件中的 key 不是 a,b,c,會出現什麼情況?請讀者自行測試。
總結一下,乙個星號可作用於所有的可迭代物件,稱為迭代器解包操作,作為位置引數傳遞給函式,兩個星號只能作用於字典物件,稱之為字典解包操作,作為關鍵字引數傳遞給函式。使用 和 * 的解包的好處是能節省**量,使得**看起來更優雅,不然你得這樣寫:
>>> d =
>>> func(a = d['a'], b=d['b'], c=d['c'])
1 2 3
>>>
到這裡,解包還沒介紹完,因為 python3.5,也就是 pep 448 對解包操作做了進一步擴充套件, 在 3.5 之前的版本,函式呼叫時,乙個函式中解包操作只允許乙個和 乙個*。從 3.5 開始,在函式呼叫中,可以有任意多個解包操作,例如:
# python 3.4 中 print 函式 不允許多個 * 操作
>>> print(*[1,2,3], *[3,4])
file "", line 1
print(*[1,2,3], *[3,4])
^syntaxerror: invalid syntax
>>>
再來看看 python3.5以上版本
# 可以使用任意多個解包操作
>>> print(*[1], *[2], 3)
1 2 3
從 3.5 開始可以接受多個解包,於此同時,解包操作除了用在函式呼叫,還可以作用在表示式中。
>>> *range(4), 4
(0, 1, 2, 3, 4)
>>> [*range(4), 4]
[0, 1, 2, 3, 4]
>>>
>>> }
新的語法使得我們的**更加優雅了,例如拼接兩個列表可以這樣:
>>> list1 = [1,2,3]
>>> list2 = range(3,6)
>>> [*list1, *list2]
[1, 2, 3, 3, 4, 5]
>>>
可不可以直接用 + 操作呢?不行,因為 list 型別無法與 range 物件相加,你必須先將 list2 強制轉換為 list 物件才能做 +操作,這個留給讀者自行驗證。
再來看乙個例子:如何優雅的合併兩個字典
>>> a =
>>> b =
>>>
>>> import copy
>>>
>>> c = copy.deepcopy(a)
>>> c.update(b)
>>> c
到此,關於 python 解包給你介紹完了,如果本文對你有收穫,請點贊、**支援。
最後給你總結一下:
自動解包支援一切可迭代物件
5分鐘教會你使用Markdown編輯神器
建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...
5分鐘讓你知道什麼是PKI
public key infrastructure pki 中文叫做公開金鑰基礎設施,也就是利用公開金鑰機制建立起來的基礎設施。但是如果這麼解釋起來,到底是個什麼東西,大家想必是沒辦法理解的。現在大家的很多重要活動都是通過網路進行的,那麼與之俱來的安全問題就顯得非常重要。同時很多安全保障機制都是基於...
5分鐘讓你的牙齒blingbling讓牙齒
很多人認為,多刷幾次牙,多嚼幾顆口香糖就可以解決。no!單靠刷牙並不能徹底清潔口腔,特別是牙齒。好吧,下面將介紹幾種方法,讓你的牙齒迅速潔淨,並且是徹底性的。方法一材料 士多啤梨一顆,發酵粉1 2茶匙。使用方法 將士多啤梨碾成糊狀,與發酵粉充分混合,用乙個柔軟的牙刷將混合物均勻塗在牙齒表面,5分鐘後...