Google 翻譯管它叫做「元組」,這是中文,但是我不懂它在說什麼。
看看英英字典好了。
a structure of data that has several parts.好像有那麼一點感覺了,我還是就叫它 Tuple 吧。
Python Tuple,唯讀的 List
可以看作是一種 immutable 的 list 資料類型,但 list 很像,但是唯讀。list = ['A', 'B'] tuple = ('A', 'B') print(type(list)) # <class 'list'> print(type(tuple)) # <class 'tuple'> print(list) # ['A', 'B'] print(tuple) # ('A', 'B')這裡的示範有很大的危險,因為 list() 與 tuple() 都是 Python 內建的函式,因此若是拿 list 與 tuple 作為變數名稱,等於改了寫 list() 與 tuple() ,容易出現很難追蹤的問題,所以不只不能用 Python 的關鍵字當變數名稱,甚至 Python 內建函式的名稱最好也當作是「保留字」,不要去用。
那為什麼不用 list,要用 tuple 呢?目前知道幾個地方適用 tuple。
第一,tuple 可以作為 dict 的 key(list 不行),因為 dict 使用 Hash 演算,所以 dict 的 key 必須是 Hashable,也就是 immutable。
d = {} d['Neil', 'TP'] = '02', '12345678' d['Neil', 'TC'] = '04', '12345678' print(d) # {('Neil', 'TP'): ('02', '12345678'), ('Neil', 'TC'): ('04', '12345678')} for first,last in d: # 同 d.keys() print(str(first) + ' ' + str(last) + ' > ' + str(d[first, last])) # Neil TP > ('02', '12345678') # Neil TC > ('04', '12345678') for name, phone in d.items(): # 小心這個差異 print(str(name) + ' > ' + str(phone)) # ('Neil', 'TP') > ('02', '12345678') # ('Neil', 'TC') > ('04', '12345678')第二,多重指定是使用 tuple 語法的概念。
d = { 'Name': 'Neil', 'Food': 'Banana'} for k,v in d.items(): print(str(k) + ' > ' + str(v)) # 上面語法可以改成 for (k,v) in d.items(): print(str(k) + ' > ' + str(v)) a = 'Neil' b = 'Banana' b, a = a, b print(a, b) # Banana, Neil # 上面語法也可以改成 (b, a) = (a, b) print(a, b) # Neil Banana第三,函式一次回傳多個值,不必再用其他容器去裝,事實上是 Python 自動打包成 tuple 並利用多重指定再解開。
List 與 tuple 都是 item 的容器,就語法上,list 是用中括號,tuple 用小括號(非必要),一樣都是用逗號區隔 item。
因為 tuple 是唯讀,Python 可以對它做一些最佳化,效能和 list 比起來會好一些。
另外有一個特別的地方,在建立只有一個 item 的 tuple 時,要多加一個逗號,不然會被誤認成其他型別。
print(type((2))) # <class 'int'> print(type((2,))) # <class 'tuple'> print(type([2,])) # <class 'list'>其實在 list 與 tuple 都是允許最後多一個逗號的。
正確來說建立 tuple 的語法,只要逗號,小括號不是必要的。
t = (0, 1, 2, 3) print(type(t)) # <class 'tuple'> print(t) # (0, 1, 2, 3) t = 0, 1, 2, 3 print(type(t)) # <class 'tuple'> print(t) # (0, 1, 2, 3) notANumber = 1,435 # 加了千分號的數字就不是 int 了,而是 tuple print(notANumber) # (1, 435)
型別轉換
可以利用 list() 與 tuple() 在 list 與 tuple 間作型別轉換。tuple1 = (0, 1, 2, 3) print(tuple1) # (0, 1, 2, 3) print(list(tuple1)) # [0, 1, 2, 3] print(tuple(list(tuple1))) # (0, 1, 2, 3)tuple() 和 list() 一樣,可以吃 sequence 做參數,而 sequence 目前知道的有 list、dict 與 str,對,就是 str。
t = tuple('Python') print(t) # ('P', 'y', 't', 'h', 'o', 'n')
tuple 操作
所有 list 的唯讀操作,像是 index 與 slice 都可以用在 tuple 上。tuple = (0, 1, 2, 3) print(tuple[2]) # 2 print(tuple.index(3)) # 3 print(tuple[1:3]) # (1, 2)也可以使用 +。
l = tuple('Py') print(l) # ('P', 'y') t = tuple('thon') print(t) # ('t', 'h', 'o', 'n') x = l + t print(x) # ('P', 'y', 't', 'h', 'o', 'n')比較運算子(>、>=、<、<=、==)也可以,逐個 item 比較直到分出結果。
l = tuple('Hello Python') t = tuple('Htllo PYTHON') print(l > t) # False print(l < t) # True由於 tuple 是 immutable,list 的 sort() 與 reverse() 這類會修改本身的 method 都不能用,但是可以用 Python 內建的函式 sorted() 與 reversed() 取代,這類內建的函式不會修改本身,而是回傳新的 tuple。
t = tuple('Python') print(t) # ('P', 'y', 't', 'h', 'o', 'n') t = sorted(t) print(t) # ['P', 'h', 'n', 'o', 't', 'y'] t = reversed(t) print(t) # <list_reverseiterator object at 0x018BF130> print(', '.join(t)) # y, t, o, n, h, P
多重指定 Tuple assignment
前面已經有稍微看過多重指定,這裡在仔細說明一下。a = 'Neil' b = 'Banana' b, a = a, b # 對調 a 與 b,不用 temp兩邊的數目必須相同,右邊可以是任意 sequence
a, b, c = 'Hey' print(a, b, c, sep = ', ') # H, e, y a, b, c = list('Hey') print(a, b, c, sep = ', ') # H, e, y a, b, c = tuple('Hey') print(a, b, c, sep = ', ') # H, e, y多重指定 / tuple 可以用在一個方便的地方:一次回傳多個值。
name, domain = 'cw1057@gmail.com'.split('@') print(name, domain) # cw1057 gmail.com t = divmod(5, 2) print(t) # (2, 1) q, r = divmod(5, 2) print(q, r) #2 1 def find_ends(li): return min(li), max(li) print(find_ends(list('993491684'))) # ('1', '9')dict.items() 也是回傳 list of tuple,可以使用多重指定讀取。
d = {'Name': 'Neil', 'Food': 'Banana', 'Sport': 'Jogging'} print(d) # {'Name': 'Neil', 'Food': 'Banana', 'Sport': 'Jogging'} for k,v in d.items(): print(str(k) + ' > ' + str(v)) # Name > Neil # Food > Banana # Sport > Jogging
dict、tuple 與 zip
可以使用 list of tuple 或者 zip 建立或修改 dict。# 用 list of tuple 建立 dict d1 = dict([('Name', 'Neil'), ('Food', 'Banana'), ('Sport', 'Jogging')]) print(d1) # {'Name': 'Neil', 'Food': 'Banana', 'Sport': 'Jogging'} # 用 zip 建立 dict d2 = dict(zip(['Name', 'Food', 'Sport'], ['Neil', 'Banana', 'Jogging'])) print(d2) # {'Name': 'Neil', 'Food': 'Banana', 'Sport': 'Jogging'} # 用 list of tuple 更新 dict d1.update([('Food', 'Pineapple'), ('Learning', 'Python')]) print(d1) # {'Name': 'Neil', 'Food': 'Pineapple', 'Sport': 'Jogging', 'Learning': 'Python'} # 用 zip 更新 dict d2.update(zip(['Name', 'Like'], ['Emma', 'Sleep'])) print(d2) # {'Name': 'Emma', 'Food': 'Banana', 'Sport': 'Jogging', 'Like': 'Sleep'}
如何選擇 str、list 或 tuple?
個別特點如下:- str 的型別受限,就是 char,且 immutable
- list 彈性最大,不限型別且為 mutable
- tuple 不限型別,但是 immutable
在某些場合,tuple 比 list 好用(或適合):
- 函式要回傳多個值
- dict 的 key
- 把許多參數打包成 tuple 傳給函式,可以避免參數過多與名稱衝突
---
---
---
沒有留言:
張貼留言