# 資研 12/29 社課講義 [**提問表單**](https://forms.gle/z4dPC1JPV6uA2q9w7) --- ## 集合 Set ![image](https://hackmd.io/_uploads/H1cb4TZvT.png) [圖源](https://steam.oxxostudio.tw/category/python/basic/set.html) ### 函式 | 函式用法 | 用途 | |:------------------------------------------:|:--------------------------------------------------------------------------------------------------------:| | `Set.add(element)` | 加入 element | | `Set_a.union(Set_b)` | 回傳 Set_a 和 Set_b 的所有元素(a聯集b,`a∪b`/`a\|b`) | | `Set_a.update(Set_b)` | 將 Set_b 所有元素併入 Set_a(a聯集b,`a∪b`/`a\|b`) | | `Set.remove(element)` | 刪去 element | | `Set.discard(element)` | 刪去 element | | `Set.pop()` | 刪去 Set 內隨機一個元素 | | `Set.clear()` | 刪去 Set 內所有元素 | | `del Set` | 刪去 Set | | `Set_a.difference(Set_b)` | 回傳在 Set_a 中但不在 Set_b 中的元素(a差集b,a-b) | | `Set_a.difference_update(Set_b)` | 刪除 Set_a 中和 Set_b 中一樣的元素(a差集b,a-b) | | `Set_a.intersection(Set_b, Set_c)` | 回傳同時存在於在 Set_a、Set_b、Set_c 中的元素(abc的交集,`a∩b∩c`/`a&b&c`) | | `Set_a.intersection_update(Set_b, Set_c)` | 刪除 Set_a 中和 Set_b、Set_c 不一樣的元素(abc的交集,`a∩b∩c`/`a&b&c`) | | `Set_a.isdisjoint(Set_b)` | 若 Set_a 和 Set_b 完全不相同則回傳 True | | `Set_a.issubset(Set_b)` | 回傳 Set_a 的所有元素是否存在於 Set_b 中(a屬於b,`a∈b`) | | `Set_a.issuperset(Set_b)` | 回傳 Set_b 的所有元素是否存在於 Set_a 中(b屬於a,`b∈a`) | | `Set_a.symmetric_difference(Set_b)` | 回傳 Set_a、Set_b 中除了2者都有的的所有元素(a對稱差集b,`a△b` or `a⊕b`/`a^b`) | | `Set_a.symmetric_difference_update(Set_b)` | 刪除 Set_a 中和 Set_b 一樣的元素,加入 Set_b 中和 Set_a 不一樣的元素(a對稱差集b,`a△b` or `a⊕b`/`a^b`) | | `Set.copy()` | 回傳 Set 的複製品 | >其中Set表**集合名稱**,element表**元素** ```python= # difference S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S3 = S1.difference(S2) print(S3) # print(S1.difference(S2)) # 輸出:{1, 3, 5} # difference_update S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S1.difference_update(S2) print(S1) # 輸出:{1, 3, 5} # intersection S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S3 = S1.intersection(S2) print(S3) # print(S1.intersection(S2)) # 輸出:{2, 4} S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S3 = {2, 3, 6, 9} S4 = S1.intersection(S2, S3) print(S4) # print(S1.intersection(S2, S3)) # 輸出:{2} # intersection_update S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S1.intersection_update(S2) print(S1) # 輸出:{2, 4} S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S3 = {2, 3, 6, 9} S1.intersection_update(S2, S3) print(S1) # 輸出:{2} # isdisjoint S1 = {1, 2} S2 = {1, 2, 3, 4, 5} print(S1.isdisjoint(S2)) # 輸出:False # issubset S1 = {1, 2} S2 = {1, 2, 3, 4, 5} print(S1.issubset(S2)) # 輸出:True # issuperset S1 = {1, 2} S2 = {1, 2, 3, 4, 5} print(S1.issuperset(S2)) # 輸出:False # symmetric_difference S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S3 = S1.symmetric_difference(S2) print(S3) # print(S1.intersection(S2)) # 輸出:{1, 3, 5, 6, 8, 10} # symmetric_difference_update S1 = {1, 2, 3, 4, 5} S2 = {2, 4, 6, 8, 10} S1.symmetric_difference_update(S2) print(S1) # 輸出:{1, 3, 5, 6, 8, 10} # copy S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'} S_ = S.copy() print(S_) # 輸出:{'Tuesday', 'Monday', 'Thursday', 'Friday', 'Wednesday'} ``` :::warning - 只有intersection可同時比較2個以上的集合 ::: --- ## 字典 Dictionaries :::warning **容器** | List | Tuple | Set | Dictionary | |:--------:|:----------:|:----------:|:----------:| | 有序 | 有序 | **無序** | 有序 | | 資料可變 | **資料不可變** | **資料不可變** | 資料可變 | ::: ### 宣告字典 - 字典表示方法:`{key : value}` ```python= D = {'fruit_a': 'apples', 'fruit_b': 'bananas'} D = dict(fruit_a= 'apples', fruit_b= 'bananas') ``` - 字典內可放置**多個元素** - 利用 `dict()` 將其他資料型態轉為字典 >key須以變數表示(命名規則與變數相同) - 一個key對應一個value,若有2個或以上value與之相對應,則以後者為準 - 字典內之元素**不限於單一資料型態** >數字、字串、布林值、列表皆可置於字典內(value) >key:僅限於string ```python= # 有2個或以上value與之相對應以後者為準 D = { 'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 4, 'Thursday': 5} print(D) # 輸出:{'Monday': 1, 'Tuesday': 2, 'Wednesday': 3, 'Thursday': 5} # 不限於單一資料型態 D = {'one': 1, 'two': True, 'three': '三', 'four': [1, 2, 3, 4]} print(D) # 輸出:{'one': 1, 'two': True, 'three': '三', 'four': [1, 2, 3, 4]} ``` ### 取得資料 #### <font color='#004B97'>**取得整個列表**</font> 1. 印出整個字典 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(D) # 輸出:{'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五': 5} ``` 2. 函式:`Dict.items()` >每一對key & value組成一個Tuple,由各個Tuple組成一個List ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} x = D.items() print(x, type(x), sep='\n') # 輸出:dict_items([('一', 'one'), ('二', 'Two'), ('三', 3), ('四', 'Four'), ('五', 5)]) # <class 'dict_items'> ``` #### <font color='#004B97'>**取得key**</font> 1. 取得所有的key;函式:`Dict.keys()` >以List回傳所有的key值 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} x = D.keys() print(x, type(x), sep='\n') # 輸出:dict_keys(['一', '二', '三', '四', '五']) # <class 'dict_keys'> ``` #### <font color='#004B97'>**取得value**</font> 1. 取得單一一個value;語法:`Dict[key]` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(D['二']) # 輸出:Two ``` 2. 取得單一一個value;語法:`Dict.get(key)` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(D.get('二')) # 輸出:Two ``` 3. 取得value;語法:`Dict.setdefault(key, value)` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(D.setdefault('一', '2')) # 輸出:one ``` 4. 取得所有的value;函式:`Dict.values()` >以List回傳所有的value值 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} x = D.values() print(x, type(x), sep='\n') # 輸出:dict_values(['one', 'Two', 3, 'Four', 5]) # <class 'dict_values'> ``` :::warning **比較** `Dict[key]` & `Dict.get(key)` & `Dict.setdefault(key, value)` - []:當該key不存在時會報錯 - get() & setdefault():當該key不存在時不會報錯 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(D['1']) ``` ``` KeyError Traceback (most recent call last) <ipython-input-53-2a44e213f754> in <cell line: 4>() 2 D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} 3 ----> 4 print(D['1']) KeyError: '1' ``` ::: ### 判斷是否存在 - 使用`in` >To determine if a specified key is present in >僅用於判斷"key"是否存在於字典中 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(('一' in D), (3 in D)) # 輸出:True False ``` ### 更改資料 #### <font color='#004B97'>**修改**</font> 1. 使用`=`,直接修改 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D['一'] = 11 print(D) # 輸出:{'一': 11, '二': 'Two', '三': 3, '四': 'Four', '五': 5} ``` 2. 使用函式:`Dict.update({key: value})` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D.update({'一': 111111}) print(D) # 輸出:{'一': 111111, '二': 'Two', '三': 3, '四': 'Four', '五': 5} ``` #### <font color='#004B97'>**添加**</font> 1. 使用`=`,直接添加 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D['六'] = 'six' print(D) # 輸出:{'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五': 5, '六': 'six'} ``` 2. 使用函式:`Dict.update({key: value})` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D.update({'六': 6}) print(D) # 輸出:{'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五': 5, '六': 6} ``` :::warning 使用`=`直接賦值與使用`update`函式時,若 該key**已有**相對應value => **更改**現有value 該key**未有**相對應value => **新增**進入字典 ::: #### <font color='#004B97'>**刪除**</font> 1. 刪除所指定key的該項資料;使用函式:`Dict.pop(key)` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D.pop('一') print(D) # 輸出:'二': 'Two', '三': 3, '四': 'Four', '五': 5} ``` 2. 刪除隨機一項資料;使用函式:`Dict.popitem()` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D.popitem() print(D) # 輸出:{'一': 'one', '二': 'Two', '三': 3, '四': 'Four'} ``` 3. 刪除所指定key的該項資料;使用函式:`del Dict[key]` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} del D['一'] print(D) # 輸出:{'二': 'Two', '三': 3, '四': 'Four', '五': 5} ``` 4. 清除該字典內的所有資料;使用函式:`Dict.clear()` ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D.clear() print(D) # 輸出:{} ``` :::warning 在下列程式碼中,x的值為D之value,所以一旦D的值有所改變,x也會隨之變化 >其他會改變字典值的,同理 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} x = D.values() print(x) D["一"] = "white" print(x) # 輸出:dict_values(['one', 'Two', 3, 'Four', 5]) # dict_values(['white', 'Two', 3, 'Four', 5]) ``` ::: ### 複製字典 法一 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D_ = D ``` 法二 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D_ = D.copy() ``` 法三 ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} D_ = dict(D) ``` ### 迭代 #### <font color='#004B97'>**items**</font> ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} for i in D.items(): print(i) # 輸出:('一', 'one') # ('二', 'Two') # ('三', 3) # ('四', 'Four') # ('五', 5) ``` #### <font color='#004B97'>**keys**</font> ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} for i in D.keys(): print(i) # 輸出:一 # 二 # 三 # 四 # 五 ``` #### <font color='#004B97'>**values**</font> ```python= D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} for i in D.values(): print(i) # 輸出:one # Two # 3 # Four # 5 ``` ### 巢狀字典 Nested Dictionaries :::warning **巢狀迴圈 Nested Loop** - 雙重迴圈(迴圈中的迴圈) - **記得使用不同變數** ```python= # 印出"九九乘法表" for i in range(1, 10): for j in range(1, 10): print(f'{i}*{j}={i*j}', end='\t') print() ``` ::: 宣告法一 ```python= Members = { 'num_1':{ 'age': 17, 'birth': '一月三十日' }, 'num_2':{ 'age': 18, 'birth': '四月十日' } } print(Members['num_1']['age']) # 輸出:17 ``` 宣告法二 ```python= num_1 = { 'age': 17, 'birth': '一月三十日' } num_2 = { 'age': 18, 'birth': '四月十日' } Members = { 'num_1': num_1, 'num_2': num_2 } print(Members['num_1']['age']) # 輸出:17 ``` ### 函式 | 函式寫法 | 用途 | |:---------------------------:|:------------------------------:| | `Dict.items()` | 取得整個列表 | | `Dict.keys()` | 取得所有key | | `Dict.get(key)` | 取得所指定key的value | | `Dict.values()` | 取得所有value | |`Dict.setdefault(key1, key2)`|回傳所指定key的value(可同時回傳多個)| | `Dict.update({key: value})` | 更改、新增字典中的資料 | | `Dict.pop(key)` | 刪除所指定key的該項資料 | | `Dict.popitem()` | 刪除隨機一項資料 | | `del Dict[key]` | 刪除所指定key的該項資料 | | `Dict.clear()` | 清除該字典內的所有資料 | | `len(Dict)` | 回傳該字典的長度 | | `dict.fromkeys(x, y)` | 回傳一個字典其key為x,value為y | ```python= # len D = {'一': 'one', '二': 'Two', '三': 3, '四': 'Four', '五':5} print(len(D)) # 輸出:5 # fromkeys x = ['Tom', 'Cindy', 'Chris'] # 可以是tuple也可以是list y = 60 D = dict.fromkeys(x, y) # 此時的dict為函式必須,非字典名稱 print(D) # 輸出:{'Tom': 60, 'Cindy': 60, 'Chris': 60} ``` ### 排序 1. 直接排序 >依照key去排序(ASCII碼) 法一 ```python= D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D)) # 輸出:['Albert', 'Cindy', 'Molly', 'Sally', 'Sam'] ``` 法二 ```python= D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D.keys())) # 輸出:['Albert', 'Cindy', 'Molly', 'Sally', 'Sam'] ``` 法三 ```python= D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D.items())) # 輸出:[('Albert', 80), ('Cindy', 65), ('Molly', 80), ('Sally', 20), ('Sam', 95)] ``` 2. 使用value來排序 :::warning **lambda** - 小型的自訂義函式(? - 語法: ```python= x = lambda a, b: a**b print(x(2, 5)) ``` ::: ```python= # 依value排序_由高到低 D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D.items(), key=lambda x:x[1])) # 輸出:[('Sally', 20), ('Cindy', 65), ('Molly', 80), ('Albert', 80), ('Sam', 95)] ``` ```python= # 依value排序_由低到高 D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D.items(), key=lambda x:-x[1])) # 輸出:[('Sam', 95), ('Molly', 80), ('Albert', 80), ('Cindy', 65), ('Sally', 20)] ``` ```python= # 依value排序_先按value降冪,若相同再按key升冪 D = { 'Sam': 95, 'Molly': 80, 'Albert': 80, 'Cindy': 65, 'Sally': 20 } print(sorted(D.items(), key=lambda x:(-x[1], x[0]))) # 輸出:[('Sam', 95), ('Albert', 80), ('Molly', 80), ('Cindy', 65), ('Sally', 20)] ``` --- ## 練習題 **Zerojudge** [**連結**](https://zerojudge.tw/) --- ## 補充資料 **推薦網站:**[**W3Schools**](https://www.w3schools.com/)