元組類型簡介 使用括弧包圍的數據結構是元組(tuple)。例如: 元組和列表一樣,都是容器型的數據結構,且都是序列,所以容器中的元素都是按照索引位置有序存放的。所以,可以進行索引取值、切片等序列通用操作。 不同的是,元組是不可變序列,無法原處修改,意味著修改元組必須創建新的元組對象。實際上元組的概念 ...
元組類型簡介
使用括弧包圍的數據結構是元組(tuple)。例如:
>>> (1,2,3)
(1, 2, 3)
>>> T = (1,2,3,)
>>> T
(1, 2, 3)
元組和列表一樣,都是容器型的數據結構,且都是序列,所以容器中的元素都是按照索引位置有序存放的。所以,可以進行索引取值、切片等序列通用操作。
不同的是,元組是不可變序列,無法原處修改,意味著修改元組必須創建新的元組對象。實際上元組的概念來源於數學,在關係型資料庫中用來表示一行數據對象,而行數據對象是固定不變的完整、穩定結構,python的元組也一樣隱含的是完整性、穩定性。
不可變序列同樣意味著可以使用hash()內置函數進行hash,也就是說它是hashable的。
hashable的類型是穩定的數據,可以放在一些需要穩定結構的地方,比如Set、dict的key,它們內部都是通過hash後的數據存放的。hashable意味著不同對象的hash值不同。比如類的實例對象全都是不同的,之所以不同是因為它們預設就是hashable的,不同對象的hash值不同。
元組的結構
元組可以看作是不可變的列表。它們的結構非常類似,都是在容器中存放元素的引用地址。
它的結構圖如下:
這個結構圖什麼意思,這裡不再贅述,如有需要,參考我對列表的介紹文章。
因為元組是不可變對象,所以修改元組數據會報錯。也就是說,元組中的保存的引用地址是不可變的。
>>> T = (1111,2222,3333,4444)
>>> T[0] = 11111
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
構造元組
直接使用括弧包圍元素即可,或者使用元組的構造函數tuple()將數據轉換成元組。例如:
>>> (1,2,3,4)
(1, 2, 3, 4)
>>> tuple("abcdef")
('a', 'b', 'c', 'd', 'e', 'f')
>>> tuple([1,2,3,4])
(1, 2, 3, 4)
括弧中可以加一個尾隨逗號:
>>> 1
1
需要註意的是,python中很多地方隱式地自動構造元組。它的隱式構造規則是這樣的:如果沒有指定括弧,又有多個值,那麼就使用元組作為容器。
>>> 1,2
(1, 2)
再者,為了區分沒有括弧的元組和單個數據對象,可以在想要作為元組元素的數據後面加上逗號。例如:
>>> 1, # 元組
(1,)
>>> (1,) # 元組
(1,)
>>> 1 # 單個數據
1
>>> (1) # 單個數據
1
元組中可以嵌套任意類型的數據對象:
>>> (1,2,(3,4))
(1, 2, (3, 4))
>>> (1,2,[3,4])
(1, 2, [3, 4])
操作元組
元組是不可變的序列。序列意味著它的元素是按索引位置有序的,序列的通用操作元組都可以使用,不可變序列意味著那些序列的修改行為都不能用,但是卻可以使用hash()內置函數對元組進行hash。
關於序列有哪些通用操作,哪些是不可變序列具有的操作,哪些是可變序列具有的操作,詳細內容參見:Python中的序列操作。
這裡簡單介紹一點基本操作。
元組支持+ *
符號操作:
>>> T = (1,2,3,4)
>>> T1 = ('a','b','c')
>>> T + T1
(1, 2, 3, 4, 'a', 'b', 'c')
>>> (1,2) + tuple("34")
(1, 2, '3', '4')
>>> T * 2
(1, 2, 3, 4, 1, 2, 3, 4)
>>> 2 * T
(1, 2, 3, 4, 1, 2, 3, 4)
可以通過+=
的方式進行二元賦值:
>>> T1 = (1,2,3)
>>> T2 = (4,5,6)
>>> T1 += T2
>>> T1
(1, 2, 3, 4, 5, 6)
元組是序列,序列類型的每個元素都是按索引位置進行存放的,所以可以通過索引的方式取得元組中的各個元素,通過切片的方式取得子元組:
>>> T = (1,2,3,4,5)
>>> T[0]
1
>>> T[:3]
(1, 2, 3)
>>> T[:]
(1, 2, 3, 4, 5)
>>> T[2:-1]
(3, 4)
但不能賦值,因為元組是不可變對象。
>>> T = (1,2,3,4)
>>> T[0] = 11
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
因為元組是不可變對象,所以可以使用hash()進行hash:
>>> hash(T)
-1883319094
>>> hash((1,2,3))
-378539185
>>> hash([1,2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
修改元組
因為元組是不可變對象,所以沒有直接方法修改元組,只能通過其它手段根據原始元組間接地構造新元組。切片返回的元組也是一種修改方式。
另外,要修改元組,可以考慮將元組轉換成可變的列表,修改之後再轉換回元組。例如:
>>> t = ('a','b','c','d')
>>> tmp = list(t)
>>> tmp[2] = "cc"
>>> t = tuple(tmp)
>>> t
('a', 'b', 'cc', 'd')
或者,通過解析的方式構造新元組,但元組解析必須註意的是元組的括弧特殊性,因為它會被當作表達式的包圍括弧,而不是元組的構造括弧。所以,只能使用tuple()包圍解析表達式。
>>> T = (1,2,3,4,5)
>>> tuple( i * 2 for i in T)
(2, 4, 6, 8, 10)
>>> ( i * 2 for i in T) # 不是元組,而是表達式括弧
<generator object <genexpr> at 0x03572150>