元組不僅不可變,而且可以通過拆包(取出元組的某些元素)來顯示某些信息
twodimpos=(10,20)
x,y=twodimpos#拆包賦值
print(x,y)
length, width, height=(4,5,6)#拆包取出三個元素
print(length)
somecities=[('beijing', 1), ('shanghai', 2),
('guangzhou',3),('shenzhen',4)]
for city in sorted(somecities):
print('%s %s' % city)#拆包分別取出兩個元素
print(somecities)
for cityname, _ in somecities:#_表示佔位符,站位符存儲城市編號,拆包取出第一個元素
print(cityname)
第一行代碼就是一個普通的元組,通過拆包分別對x和y賦值,第4行和第5行表示用元組分別初始化三個變量
第6行是一個列表元組,第一個for循環將元組中的元素分別顯示出來,第二個for循環用佔位符來獲取城市的名字
Python中可以不使用中間變量來交換兩個值,這也是拆包的應用之一
twodimpos=(10,30)
x,y=twodimpos
print(x,y)
x,y=y,x
print(x,y)
x,y組合的實質就是一個元組,可以通過交互模式查看
所以可以通過拆包來交換值
os.path.split函數接受一個文件所在的路徑,返回文件路徑和文件組成的元組
可以通過佔位符和拆包取出文件名
import os
print(os.path.split('/home/xiaocui/work/fluent-python/tuple.py'))
_, filename=os.path.split('/home/xiaocui/work/fluent-python/tuple.py')
print(filename, _)
佔位符一般表示忽略的元素,但是本質依然是個變量,可以正常使用和打印
還可以將元組作爲參數傳入函數,用*將元組拆開,因此也實現了通過*將任意數量的參數傳入一個函數中
print(divmod(20,8))
#divmod函數接收兩個數字,返回一個元組,元組的第一個元素是商,第二個元素是餘數
para=(20,8)
print(divmod(*para))#傳入一個元組,並通過*拆包,如果定義的參數數量更多,也可以傳入更多的參數,因爲*可以將任意數量的參數傳入一個函數中
m,n=divmod(*para)
print(m,n)
結果顯示,上述兩種形式的代碼的結果完全相同
通過*不僅可以將任意數量的參數傳入一個函數中,也可以通過*來進行平行賦值
a,b,c,*other=range(10)
print(a,b,c,other)
a,b,c,*other,d,e,f=range(10)
print(a,b,c,other,d,e,f)
a,b,c,*other=range(3)
print(a,b,c,other)
上述例子表明,*前綴可以出現在中間 變量前面,如果*修飾的變量沒有被賦值,則該變量是一個空列表
a,b,c,other的組合其實也是一個元組,和x,y的組合一樣
嵌套元組的拆包
嵌套元組就是元組中的元素還是元組,即使這樣,Python依舊能準確拆包
manpos=[('tom', (10,20)), ('jerry', (10,50))]
for name, (x,y) in manpos:
print(name, x, y)
if (y>30):
print(name, x, y)
上述代碼將Tom和Jerry的具體元組座標用一個元組接收,從而實現了在將列表中的元組元素中的元組進行拆包
具名元組(namedtuple)
具名元組在collection包中,其中的namedtuple用來構建元組和類
代碼示例:
from collections import namedtuple#導入namedtuple
manpostuple=namedtuple('manpostuple', 'name pos')#創建了一個叫manpostuple的類,在使用該類生成對象時,必須傳入name參數和pos參數,相當於manpostuple的__init__函數是這樣的:def __init__(self, name, pos):
tom1=manpostuple('tom1', (10,20))#創建兩個對象,並傳入一個字符串和一個元組
jerry1=manpostuple('jerry1', (10,50))
print(tom1, jerry1)#打印出兩個帶名字的元組,元組的名字是manpostuple,兩個元素分別是name和pos
print(tom1.name,tom1.pos, tom1[0], tom1[1])#因爲tom既是類的對象,也是元組,所以可以用點訪問,也能用下標訪問
通過上述代碼可知,具名元組(namedtuple)創建的是一個帶有名字的元組,同時也是一個類,類名是namedtuple的第一個參數,類的成員變量是namedtuple的第二個參數
具名元組的一些屬性和函數
繼續以上述代碼爲例,執行如下操作
print(manpostuple._fields)#_fields屬性將具名元組manpostuple的參數打包成員組,這裏將屬性name和pos打包成元組
dog1=('dog1',(10,30))
print(manpostuple(*dog1))#將dog1通過*拆包,傳入具名元組manpostuple
print(manpostuple._make(dog1))#等效第三行,所以_make函數的作用就是將dog1拆包,然後生成一個manpostuple對象
print(manpostuple._make(dog1)._asdict())#將manpostuple對象dog1轉換爲OrderedDict對象
for key, val in manpostuple._make(dog1)._asdict().items():#打印字典中的key value
print(key, val)
參考:
《流暢的Python》
歡迎大家評論交流,作者水平有限,如有錯誤,歡迎指出