1. 程式人生 > >每日一python(9):基礎資料結構 ---- 元組

每日一python(9):基礎資料結構 ---- 元組

Tuple是Python內建的另一種資料型別,元組。Tuple也是一種有序的集合,tuple和list非常類似,但是tuple一旦初始化就不能修改。

比如:同樣是列出同學的名字,如下:

>>> classmates = ('Bob', 'Tract', 'Jack')
>>> classmates
('Bob', 'Tract', 'Jack')

現在,classmates這個tuple不能變了,它也沒有append(),insert()這樣的方法。其他獲取元素的方法和list是一樣的,你可以正常地使用classmates[0] , classmates[-1] ,但不能賦值成另外的元素。如下:

>> classmates = ('Bob', 'Tract', 'Jack')
>>> classmates
('Bob', 'Tract', 'Jack')
>>> classmates[0]
'Bob'
>>> classmates.append('Judy')
Traceback (most recent call last):
  File "<pyshell#61>", line 1, in <module>
    classmates.append('Judy')
AttributeError: 'tuple' object has no attribute 'append'
>>> classmates.insert(1, 'Judy')
Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    classmates.insert(1, 'Judy')
AttributeError: 'tuple' object has no attribute 'insert'

注意: 當定義一個tuple時,在定義的時候,tuple的元素就必須被確定下來。如:

>>> t = (1, 2)
>>> t
(1, 2)

1. 新建元組

t1 = ('Python','123',111)
print(t1)

列印結果:
在這裡插入圖片描述

如果新建時沒有用( )括號括起來,只用逗號進行分隔,python也會把它認做為元組,如:

t2 = 'Python','123',111
print(t2)

列印結果:
在這裡插入圖片描述

如果新建元組中只有一個值,那麼請記得在這個值後邊加上逗號如果沒有逗號,python只當把它當做整型來處理


如:

t3 = 1,
t4 = (1,)
t5 = 1
t6 = (1)
print("t3和t4: ", t3, t4)
print("t5和t6: ", t5, t6)

列印結果:
在這裡插入圖片描述

新建空元組如下:

t7 = ()
print(t7)

列印結果:
在這裡插入圖片描述

2. 將列表轉換為元組

要將列表或字串轉換為元組,用到元組函式tuple()即可,如:

list = [1, 2, 'python']
str = 'String'
t8 = tuple(list)   # 括號裡的是列表
t9 = tuple(str)    # 括號裡的是字串
print(t8)
print(t9)

列印結果:
在這裡插入圖片描述

3. 獲取元組中的資料

t = (1,2,3,4,5)
print("第1個元素:", t[0])
print("第2個元素:", t[1])

列印結果:
在這裡插入圖片描述

4. 元組的index()函式

元組 index() 方法用於從元祖中找出某個物件第一個匹配項的索引位置,如果這個物件不在元祖中會報一個異常。

index() 方法:

t.index(obj[,start=0[,end=len(T)]])

引數說明:

  • obj – 指定檢索的物件。
  • start – 可選引數,開始索引,預設為0。(可單獨指定)
  • end – 可選引數,結束索引,預設為元祖的長度。(不能單獨指定)
t = ('x', 'y', 1, 'x', 2, 'x')
print(t.index('x'))
print(t.index('x', 1))
print(t.index('x', 4))
print(t.index('y'))
print(t.index('y', 2))

列印結果:
在這裡插入圖片描述

說明:
最後的報錯,是因為從索引位置2開始向後,不存在’y’元素了,所以儲存在的異常。

5. 元組的count()函式

元組 count() 方法用於統計某個元素在元祖中出現的次數。

count() 方法:

t.count(obj)

引數說明:

  • obj – 元祖中統計的物件。
t = (123, 'Google', '123', 'Taobao', 'xyz', 123)
print("123 元素個數 : ", t.count(123))
print("'678' 元素個數 : ", t.count('678'))
print("'Taobao' 元素個數 : ", t.count('Taobao'))

列印結果:
在這裡插入圖片描述

6. 元組的相對不可變性(轉自: Python 元組的相對不可變性

Python中的元組是一種類似於列表的容器型別,但列表是可變的而元組是不可變。
元組本身是不可變的,但是它所包含的元素的可變性取決於該元素的屬性

首先來看一個問題:

>>> t = (1, 2, [30, 40])
>>> t[2] += [50, 60]

以上兩個表示式到底會發生下面 4 種情況下的哪一種?

  1. t 變成 (1, 2, [30, 40, 50, 60])。
  2. 因為 tuple 不支援對它的元素賦值,所以會丟擲 TypeError 因為 tuple 不支援對它的元素賦值,所以會丟擲 TypeError 異常。
  3. 以上兩個都不是。
  4. 1 和 2 都是對的。

剛看到上面的問題,可能正常的大多數人會選1,也有可能會選2。
但結果究竟是啥呢?我們執行一下,看一下結果如何:

>>> t = (1, 2, [30, 40])
>>> t[2] += [50, 60]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
(1, 2, [30, 40, 50, 60])

看到上面的執行結果,其實答案就一目瞭然了, 自然4是正確答案了。

6.1 變數不是盒子

在回答這個問題之前我們來了解 Python 中的變數。

“變數是盒子”這樣的比喻經常被使用,但是這有礙於理解面嚮物件語言中的引入式變數。如下所示的互動式控制檯中,無法使用“變數是盒子”做解釋。

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]

如果把變數想象為盒子,那麼無法解釋 Python 中的賦值。Python 變數類似於 Java 中的引用式變數,因此最好把它們理解為附加在物件上的標註

在這裡插入圖片描述

為了理解 Python 中的賦值語句,應該始終先讀右邊(對引用式變數來說,說把變數分配給物件更合理。畢竟,物件在賦值之前就建立了。)。物件在右邊建立或獲取,在此之後左邊的變數才會繫結到物件上,這就像為物件貼上標註。

6.2 元組不可變性指的是?

元組與多數 Python 集合(列表、字典、集,等等)一樣,儲存的是物件的引用。如果引用的元素是可變的,及時元組本身不可變,元素依然可變。也就是說,元組的不可變性其實指 tuple 資料結構的物理內容(即儲存的引用)不可變,與引用的物件無關。

我們看一下示例:

>>> t = (1, 2, [30, 40])
>>> id(t[-1])   # 檢視t[-1]的標識
17159496
>>> t[-1].append(99)
>>> t
(1, 2, [30, 40, 99])
>>> id(t[-1])
17159496

我們看到:檢視 t[-1] 列表的標識可以看到標識沒變,只是值變了。

回到最初的問題,如果寫成如下程式碼:

>>> t = (1, 2, [30, 40])
>>> t[2].extend([50, 60])
>>> t
(1, 2, [30, 40, 50, 60])

我們發現就可以避免異常。

因此,引發異常的操作在於對不可變元組的元素進行了賦值。這也對前面所說的變數是標註作了很好的註釋。在分配給變數前物件就已經建立,所以儘管後來的賦值操作引發了異常,列表物件還是發生了變化。