Python3 教學 #02 (Ch5: List、Tuple、Set、Dictionary)
本章會介紹Python內建幾個重要的資料結構:List、Tuple、Set、Dictionary
NumPy讓大家在使用Python時可以專注在資料處理邏輯上,不需要花時間在資料結構撰寫!
在進行矩陣運算時也會用到許多這些資料結構的觀念,因此這部分的學習對於機器學習、深度學習、人工智慧都有深遠的影響!
(以下語法教學都是以Python 3.6撰寫。)
宣告
1 2 3 |
>>> my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100] >>> print(my_list) [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100] |
方法
list.append(element)
將元素x加入至list的尾端,等同於語法『 list[len(list):] = [x] 』
1 2 3 4 5 6 7 8 9 10 11 |
>>> print(my_list) [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100] >>> my_list.append(100) #將元素[100]新增至my_list的尾端 >>> print(my_list) #印出新增元素[100]之後的結果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100] >>> my_list[len(my_list):] = [9] #將元素[9]新增至my_list的尾端 >>> print(my_list) #印出新增元素[9]之後的結果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9] >>> my_list.append([1, 1, 1, 1]) #將一個list新增至my_list的尾端 >>> print(my_list) #印出新增元素[1, 1, 1, 1]之後的結果 [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] |
list.extend(L)
將L這個List增加至list之中,等同於語法『 list[len(list):] = L 』
1 2 3 4 5 6 7 8 9 |
>>> #先確認my_list的內容 >>> print(my_list) [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] >>> #建立your_list >>> your_list = [0, 0, 0, 0, 0] >>> #將my_list的內容增加至your_list之後 >>> your_list.extend(my_list) >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] |
list.insert(i, element)
將element插入至第 i 個index的位置
1 2 3 4 5 6 7 |
>>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] >>> #將元素[9]插入至your_list位置第5的地方 >>> your_list.insert(5, 9) >>> #印出結果 >>> print(your_list) [0, 0, 0, 0, 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] |
list.remove(value)
刪除list中特定元素值的第一個元素
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> print(your_list) [0, 0, 0, 0, 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] >>> #把your_list的第1個值為9的元素刪除 >>> your_list.remove(9) >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] >>> #再把your_list的第1個值為9的元素刪除 >>> your_list.remove(9) >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100, 100, 9, [1, 1, 1, 1]] >>> your_list.remove([1, 1, 1, 1]) >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100, 100, 9] |
list.pop(i)
取出list中指定第 i 個元素,並且將該元素刪除
list.pop()
取出list中最尾端的元素,並且將該元素刪除(像是堆疊Stack那樣)
在實務應用上可以用一個變數來接收pop出來的元素喔!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
>>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100, 100, 9] >>> #pop會取出該元素,所以沒有將元素指定給其他變數,會在執行結束後印出該元素 >>> your_list.pop(17) 100 >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100, 9] >>> #實務上可以用一個變數來接收pop出來的元素 >>> my_pop = your_list.pop() >>> print(my_pop) 9 >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100] >>> #這是要求pop超出your_list範圍的錯誤訊息 >>> your_list.pop(20) Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: pop index out of range |
list.index(value)
找出特定元素值的第一個位置(index)
1 2 3 4 5 6 7 8 9 |
>>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100] >>> your_list.index(9) 13 >>> #若找不到的話,會回傳下列錯誤 >>> your_list.index(20) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 20 is not in list |
list.count(value)
列出特定元素值的元素數量
1 2 3 4 5 6 7 8 9 |
>>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100] >>> your_list.count(9) 2 >>> your_list.count(0) 5 >>> #如果找不到元素值,則回傳結果為0 >>> your_list.count(20) 0 |
list.sort()
將list由小至大排序
list.reverse()
將list由大至小排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
>>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100] >>> #為了顯示排序效果,先插入一筆資料在your_list的index=2的位置 >>> your_list.insert(2, 55) >>> print(your_list) [0, 0, 55, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 100] >>> #讓your_list由小到大排序 >>> your_list.sort() >>> print(your_list) [0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 55, 100] >>> #讓your_list由大到小排序 >>> your_list.reverse() >>> print(your_list) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0] |
list.copy()
拷貝一個list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
>>> print(your_list) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0] >>> your_list.copy() [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0] >>> #拷貝your_list給my_copy >>> my_copy = your_list.copy() >>> print(my_copy) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0] >>> #增加元素[99]到my_copy >>> my_copy.append(99) >>> #看來存取的記憶體位址不同,證明兩者是互不影響的 >>> print(my_copy) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 99] >>> print(your_list) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0] >>> |
list.clear()
清除list內所有資料
1 2 3 4 5 |
>>> print(my_copy) [100, 55, 10, 9, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 99] >>> my_copy.clear() >>> print(my_copy) [] |
Tuple就跟List很像,但是一經宣告之後,便無法修改內容!
1 2 3 4 5 6 7 8 9 10 11 |
>>> #用小括號包著元素宣告Tuple >>> t = (1, 2, 3, 4, 5) >>> print(t) (1, 2, 3, 4, 5) >>> print(t[0]) 1 >>> #嘗試修改Tuple的內容就會出錯! >>> t[2] = 9 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment |
如果需要將list轉型成tuple可以用『tuple(變數)』來完成轉型!
1 2 3 4 5 6 7 |
# list a = [1, 2, 3, 4] print(type(a)) # convert a to tuple b = tuple(a) print(type(b)) |
1 2 |
<class 'list'> <class 'tuple'> |
在集合(Set)裡面存放的是一群無順序且唯一的元素!
set(element)
用set()宣告集合!
1 2 3 4 5 |
>>> #宣告Set >>> my_set = set(["Apple", "Banana", "Coconut", "Banana", "Dragon Fruit"]) >>> #Set會自動去除重複值 >>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} |
in
確認元素是否存在於Set之中
1 2 3 4 5 6 |
>>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} >>> 'Apple' in my_set True >>> 'apple' in my_set False |
差集(Difference)
SetA – SetB,輸出結果為SetA有,而SetB沒有的元素
1 2 3 4 5 6 7 |
>>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} >>> print(your_set) {'Apple', 'Lemon', 'Banana'} >>> #差集運算,列出my_set有,而your_set沒有的元素 >>> print(my_set - your_set) {'Dragon Fruit', 'Coconut'} |
聯集(Union)
回傳兩個Set所有的元素
1 2 3 4 5 6 7 |
>>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} >>> print(your_set) {'Apple', 'Lemon', 'Banana'} >>> #聯集運算 >>> print(my_set | your_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana', 'Lemon'} |
交集(Intersection)
回傳兩個Set都要存在的元素
1 2 3 4 5 6 7 |
>>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} >>> print(your_set) {'Apple', 'Lemon', 'Banana'} >>> #兩個Set同時存在的元素 >>> print(my_set & your_set) {'Apple', 'Banana'} |
對稱差集合(Symmetric Difference)
這個原理有點複雜,點這裡看詳細解釋:Symmetric Difference(Wikipedia)
但如果是只有兩個Set做運算的話,結果會是(SetA或SetB)而且(去除SetA、SetB都有的元素)!
1 2 3 4 5 6 |
>>> print(my_set) {'Apple', 'Dragon Fruit', 'Coconut', 'Banana'} >>> print(your_set) {'Apple', 'Lemon', 'Banana'} >>> print(my_set ^ your_set) {'Coconut', 'Dragon Fruit', 'Lemon'} |
字典(Dictionary),這算是很經典的資料結構之一。
使用大括號宣告字典即可
宣告
1 2 3 4 |
>>> #宣告字典 >>> dict_fruit = {"Apple":16, "Banana":9, "Coconut":34, "Dragon Fruit":39} >>> print(dict_fruit) {'Apple': 16, 'Banana': 9, 'Coconut': 34, 'Dragon Fruit': 39} |
修改數值
1 2 3 4 5 6 |
>>> print(dict_fruit['Apple']) 16 >>> #Apple修改為45 >>> dict_fruit['Apple'] = 45 >>> print(dict_fruit['Apple']) 45 |
字典Key清單
取出字典內的Key值
1 2 3 4 5 6 |
>>> dict_fruit.keys() dict_keys(['Apple', 'Banana', 'Coconut', 'Dragon Fruit']) >>> #將字典的key值轉成一個List,且存入list_fruit變數中 >>> list_fruit = list(dict_fruit.keys()) >>> print(list_fruit) ['Apple', 'Banana', 'Coconut', 'Dragon Fruit'] |
確認字典是否存在某特定Key
1 2 3 4 5 |
>>> print(dict_fruit) {'Apple': 45, 'Banana': 9, 'Coconut': 34, 'Dragon Fruit': 39} >>> #判斷「Lemon」是否存在於dict_fruit >>> 'Lemon' in dict_fruit False |
刪除字典裡的元素
1 2 3 4 5 6 |
>>> print(dict_fruit) {'Apple': 45, 'Banana': 9, 'Coconut': 34, 'Dragon Fruit': 39} >>> #刪除「Banana」 >>> del dict_fruit['Banana'] >>> dict_fruit {'Apple': 45, 'Coconut': 34, 'Dragon Fruit': 39} |
我們都知道List和Tuple最大的差異在於Tuple的內容是創建之後就無法修改的。
但List & Tuple這兩個資料結構該怎麼運用呢?
我相信Tuple的運用情境肯定比較困難,終於找到一個情境:
用Tuple實作multi-key Dict
1 2 3 4 |
key_val= {('andy','wang'): 'NCU', ('emily', 'chen'): 'NTU', ('john', 'tsai'): 'UCLA'} print(key_val.keys()) print(key_val['andy', 'wang']) print(key_val['john', 'tsai']) |
1 2 3 |
dict_keys([('emily', 'chen'), ('john', 'tsai'), ('andy', 'wang')]) NCU UCLA |
請問以上各種在用途上有甚麼舉例?謝
抱歉,前陣子在忙,導致現在才能回覆!
在網路上找到一個蠻有趣的使用案例,已經添加到本文最下方!
另一個使用案例,建議您觀察看看物件傳入Array與存取Array的方式(call-by-value/call-by-address),再來決定何時可以使用Tuple來保護物件內的共用變數。