---
# System prepended metadata

title: 資研 12/29 社課講義
tags: [社課講義, 資研]

---

# 資研 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/)