5分鐘,關於Python 解包,你需要知道的一切

2021-09-20 05:02:33 字數 3994 閱讀 2286

解包在英文裡叫做 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分鐘後...