Python進階4——元組與拆包

元組不僅不可變,而且可以通過拆包(取出元組的某些元素)來顯示某些信息

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》

 

歡迎大家評論交流,作者水平有限,如有錯誤,歡迎指出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章