Python元組拆包撿到8倍鏡快準狠

元組拆包

元組是不可變列表,列表是經過索引取值的,元組也是:python

tuple_test = (1, 2, 3)
a = tuple_test[0]
b = tuple_test[1]
c = tuple_test[2]

但Python是出了名的一行代碼解決問題,元組拆包就是精髓技術之一:數據庫

a, b, c = tuple_test
print("%s %s %s" % tuple_test)

把元組一一對應拆出來,就叫作元組拆包。拆包有個要求,元組中的元素數量必須跟接受這些元素的空擋數一致,不然會報錯:ssh

tuple_test = (1, 2, 3)
a, b = tuple_test  # ValueError: too many values to unpack (expected 2)

_佔位符函數

使用_佔位符能夠解決這個問題:ui

tuple_test = (1, 2, 3)
a, b, _ = tuple_test

這樣就只獲取到部分數據了,這在取函數返回值時特別有用,好比:調試

import os

_, filename = os.path.split("/home/dongfanger/.ssh/idrsa.pub")
print(filename)  # "idrsa.pub"

*前綴rest

當返回值特別多時,_佔位符寫起來麻煩,能夠用*來處理剩下的元素:code

>>> a, b, *rest = range(5)
>>> a, b, *rest
(0, 1, [2, 3, 4])

注意rest是個列表,若是沒有足夠元素,會返回空列表:對象

>>> a, b, *rest = range(2)
>>> a, b, *rest
(0, 1, [])

*前綴變量能放在任意位置,好比,放在中間:blog

>>> a, *body, c, d = range(5)
>>> a, body, c, d
(0, [1, 2], 3, 4)

放在前面:

>>> *head, b, c, d = range(5)
>>> head, b, c, d
([0, 1], 2, 3, 4)

實在是妙啊。

*還有一個做用,把元組拆開做爲函數參數:

>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)
(2, 4)

經典寫法*args就是這個道理。

嵌套元組拆包

嵌套元組是指元組中有元組,好比(1, 2, 3, (4, 5)),對於嵌套元組,你可能會想要拆兩遍:

tuple_nest_test = (1, 2, 3, (4, 5))
a, b, c, d = tuple_nest_test
x, y = d
print(a, b, c, x, y)

實際上能一步到位:

tuple_nest_test = (1, 2, 3, (4, 5))
a, b, c, (x, y) = tuple_nest_test
print(a, b, c, x, y)

交換兩個變量的值

元組拆包提供了語法糖,對於交換兩個變量的值的常規寫法:

temp = a
a = b
b = temp

能夠切換爲優雅寫法:

b, a = a, b

具名元組

元組很像數據庫表記錄,除了沒有表名和字段名,collections.namedtuple具名元組補償了這個缺憾,它是一個工廠函數,能夠用來構建一個帶字段名的元組和一個有名字的類,好比:

import collections

# 定義
Card = collections.namedtuple("Card", ["rank", "suit"])
# 初始化
card_test = Card("J", "hearts")
# 使用
print(card_test.rank)  # J
print(card_test[1])  # hearts

Card是表名,有兩個表字段rank和suit。

定義具名元組須要2個參數,第1個參數是類名,第2個參數是字段名,既能夠是可迭代對象(如列表和元組),也能夠是空格間隔的字符串:

Card = collections.namedtuple("Card", ("rank", "suit"))
Card = collections.namedtuple("Card", "rank suit")

初始化時以一串參數形式傳入構造函數:

card_test = Card("J", "hearts")

既能夠經過.運算符,也能夠用索引來取值:

print(card_test.rank)
print(card_test[1])

這個帶名字的元組,對調試程序有很大幫助。

列表與元組

元組是不可變列表,它們就像雙胞胎,長相相似,內在性格卻有不一樣:

黃色列表獨有,紅色元組特有,元組居然還多了個s.__getnewargs__()方法!從表中能夠清楚地看到,除了跟增減元素相關的方法以外,元組支持列表的其餘全部方法。

列表也能拆

既然列表和元組是孿生兄弟,那必然也有共同技能:

list_test = [1, 2, 3]
a, b, c = list_test
>>> divmod(20, 8)
(2, 4)
>>> t = [20, 8]  # 換成列表
>>> divmod(*t)
(2, 4)

列表拆包,也是ok的。

小結

本文介紹了Python神奇操做元組拆包,藉助_佔位符和*前綴能夠進行更加靈活的取值,具名元組實際用的還比較少,不過看一些源碼是有的。文章最後比較了列表和元組的差別,列表也能拆包。列表(list)、元組(tuple),以及字符串(str),都有一個共同操做:切片。

參考資料:

《流暢的Python》

相關文章
相關標籤/搜索