# 資研 12/22 社課講義
[**提問表單**](https://forms.gle/z4dPC1JPV6uA2q9w7)
---
## 列表 List
:::warning
**資料型態**
| Text | Numeric | boolean |
|:----:|:-------:|:------:|
| `string` | `int`、`float` | `bool` |
- 容器
| Sequence | Mapping | Set |
|:--------:|:-------:|:----:|
| `list`、`tuple` | `dict` | `set` |
:::
### 函式
| 函式用法 | 用途 |
|:-------------------------:|:--------------------------------------------------------------:|
| `List.insert(n, element)` | 在 n 的位置插入 element |
| `List.append(element)` | 在 List 的**尾端**插入 element |
| `List_a.extend(List_b)` | 將 List_b 所有元素併入 List_a |
| `List.remove(element)` | 刪去**首次出現**的 element |
| `List.pop(n)` | 刪去位於 n 的元素並返回刪去的值 |
| `del List[n]` | 刪去於位於 n 的元素 |
| `List.clear()` | 刪去 List 內所有元素 |
| `List.sort()` | 將 List 內的元素依 ASCII 碼**小到大**排序(可使用reverse參數) |
| `sorted()` | 將 List 內的元素依 ASCII 碼**小到大**排序 |
| `List.reverse()` | 將 List 內的元素順序反轉 |
| `List.copy()` | 回傳 List 的複製品 |
| `List.index(element)` | 回傳 List 內第一次出現 element 的位置 |
| `List.count(element)` | 回傳 List 內 element 的出現次數 |
| `sum(List)` | 當 List 全為數字時回傳 List 內數字總和 |
>其中List表**列表名稱**,n表**index**,element表**元素**
```python=
# index
L = ['Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday']
i = L.index('Thursday')
print(i)
# 輸出:1
# count
L = ['Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday']
i = L.count('Thursday')
print(i)
# 輸出:2
# sum
L = [10, 11, 12, 13, 14]
print(sum(L))
# 輸出:60
```
:::warning
### **比較**
6. copy & '=' & list()
- 差別:除list()還有轉換期他資料型態成列表外,沒有太大差異
```python=
# copy(不另外賦值)
L = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(L.copy())
# 輸出:['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
# '='
L = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
L_ = L
print(L_)
# 輸出:['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
# list(複製)
L = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
L_ = list(L)
print(L_)
# 輸出:['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
# list(轉換)
L = 'M o n d a y'
L_ = list(L.split())
print(type(L), type(L_), '\n', L_)
# 輸出:<class 'str'> <class 'list'>
# ['M', 'o', 'n', 'd', 'a', 'y']
```
:::
### 練習
- 例題:請利用L列表,寫一個程式計算出有幾種不一樣的數字?
```
L = [12, 22, 23, 45, 26,
33, 44, 32, 22, 72,
83, 76, 10, 12, 33,
56, 21, 72, 77, 19]
```
```python=
num_L = []
for i in L:
if i not in num_L: num_L.append(i)
else: continue
print(len(num_L), num_L)
```
---
## 元組 Tuple
:::warning
**容器**
| List | Tuple | Set | Dictionary |
|:--------:|:----------:|:----------:|:----------:|
| 有序 | 有序 | **無序** | 有序 |
| 資料可變 | **資料不可變** | **資料不可變** | 資料可變 |
:::
### 宣告元組
- 元組表示方法:`()`
```python=
T = ('apple', 'bananas')
T = tuple(['apple', 'bananas'])
```
- 和列表很像,雖然不可改變其中的資料,但電腦存取及處理速度較快
- 元組內可放置**多個元素**
- 利用 `tuple()` 將其他資料型態轉為元組
- <font color="#CE0000">**宣告只有一個元素的元組,須加上</font>`,`**
- 元組內之元素**不限於單一資料型態**
>數字、字串、布林值皆可置於元組內
```python=
# 宣告單一元素元組
T_ = ('banana',)
print(type(T_))
# 輸出:<class 'tuple'>
# 多個元素
T1 = ('apple', 'bananas')
print(T1, type(T1))
# 輸出:('apple', 'bananas') <class 'tuple'>
# 將其他東西轉成元組
L = ['apple', 'bananas']
print(type(L))
T1_ = tuple(L)
print(T1_, type(T1_))
# 輸出:<class 'list'>
# ('apple', 'bananas') <class 'tuple'>
# 不限單一資料型態
T2 = ('a', 1, True)
print(T2)
# 輸出:('a', 1, True)
```
### 讀取資料
- 利用`index`來限制取的範圍
- 使用`[a:b]`;a為開頭的index,b為<font color="#CE0000">**結尾前**</font>的index
>"-1"表示倒數,從-1開始
>不包含b
### 判斷是否存在
- 使用`in`
### 迭代
- 元組屬於**可迭代物件**
### len()
- 可回傳容器長度
- 適用於:`string`、`List`、`Tuple`...
```python=
# string
s = 'Today is 12/22.'
print(len(s))
# 輸出:15
# List
L = [12, 'Merry Christmas']
print(len(L))
# 輸出:2
# Tuple
T = (123, 22, '!!!今天耶晚')
print(len(T))
# 輸出:3
```
### 變更資料
- **元組本身無法更改資料**
- 轉成其他資料型態,作變更再轉回來
```python=
T = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 5)
print(type(T))
L = list(T)
print(type(L), L[4])
L[4] = 'Friday'
print(L)
T_ = tuple(L)
print(type(T_), T_)
```
```
輸出:
<class 'tuple'>
<class 'list'> 5
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
<class 'tuple'> ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
```
### unpack
```python=
T = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
(a, b, c, d, e) = T
print(a, b, c, d, e)
# 輸出:Monday Tuesday Wednesday Thursday Friday
```
### 合併
- 可利用`+`、`*`將2個或2個以上的元組合併
```python=
# +
T1 = ('Monday', 'Tuesday')
T2 = ('Wednesday',)
T3 = ('Thursday', 'Friday')
print(T1+T2+T3)
# 輸出:('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
# *
T = ('Monday', 'Tuesday')
T_ = T*2
print(T_)
# 輸出:('Monday', 'Tuesday', 'Monday', 'Tuesday')
```
### 函式
| 函式用法 | 用途 |
|:-------------------------:|:--------------------------------------------------------------:|
| `Tuple.index(element)` | 回傳 Tuple 內第一次出現 element 的位置 |
| `Tuple.count(element)` | 回傳 Tuple 內 element 的出現次數 |
| `sum(List)` | 當 Tuple 全為數字時回傳 Tuple 內數字總和 |
>其中Tuple表**元組名稱**,n表**index**,element表**元素**
```python=
# '='
T = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
T_ = T
print(T_)
# 輸出:('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
# tuple(複製)
T = ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
T_ = tuple(T)
print(T_)
# 輸出:('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
# index
T = ('Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday')
i = T.index('Thursday')
print(i)
# 輸出:1
# count
T = ('Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday')
i = T.count('Thursday')
print(i)
# 輸出:2
# sum
T = (10, 11, 12, 13, 14)
print(sum(T))
# 輸出:60
```
---
## 集合 Set

[圖源](https://steam.oxxostudio.tw/category/python/basic/set.html)
### 宣告集合
- 集合表示方法:`{}`
```python=
S = {'apple', 'bananas'}
S = set(['apple', 'bananas'])
```
- 集合內可放置**多個<font color="#CE0000">不同</font>元素**
- 利用 `set()` 將其他資料型態轉為集合
- 不可使用index讀取資料
- **只可新增或刪除資料,無法更改其值**
- 集合內之元素**不限於單一資料型態**
>數字、字串、布林值皆可置於集合內
```python=
# 多個元素
S1 = {'apple', 'bananas'}
print(S1, type(S1))
# 輸出:{'bananas', 'apple'} <class 'set'>
# 將其他東西轉成集合
T = ('apple', 'bananas')
print(type(T))
S1_ = tuple(T)
print(S1_, type(S1_))
# 輸出:<class 'tuple'>
# ('apple', 'bananas') <class 'tuple'>
# 不限單一資料型態
S2 = {'a', 1, True}
print(S2)
# 輸出:{1, 'a'}
```
>1和True在布林值中為同一種數值,**不會同時存在**
### 判斷是否存在
- 使用`in`
### 迭代
- 集合屬於**可迭代物件**
### 函式
| 函式用法 | 用途 |
|:------------------------------------------:|:--------------------------------------------------------------------------------------------------------:|
| `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`) |
| `Set_a.intersection_update(Set_b, Set_c)` | 刪除 Set_a 中和 Set_b、Set_c 不一樣的元素(abc的交集,`a∩b∩c`/`a&b`) |
| `Set_a.isdisjoint(Set_b)` | 若 Set_a 和 Set_a 完全不相同則回傳 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=
# add
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.add('Saturday')
print(S)
# 輸出:{'Tuesday', 'Monday', 'Thursday', 'Saturday', 'Friday', 'Wednesday'}
# union
S1 = {'Monday', 'Tuesday', 'Wednesday'}
S2 = {'Thursday', 'Friday'}
S3 = S1.union(S2)
print(S3) # print(S1.union(S2))
# 輸出:{'Tuesday', 'Monday', 'Thursday', 'Friday', 'Wednesday'}
# update
S1 = {'Monday', 'Tuesday', 'Wednesday'}
S2 = {'Thursday', 'Friday'}
S1.update(S2)
print(S1)
# 輸出:{'Tuesday', 'Monday', 'Thursday', 'Friday', 'Wednesday'}
# remove
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.remove('Monday')
print(S)
# 輸出:{'Tuesday', 'Thursday', 'Friday', 'Wednesday'}
# discard
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.discard('Monday')
print(S)
# 輸出:{'Tuesday', 'Thursday', 'Friday', 'Wednesday'}
# pop
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.pop()
print(S)
# clear
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.clear()
print(S)
# 輸出:set()
# del
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
del S
print(S)
# 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
1. **update & union**
- 差別:update會改變原集合的值;union則是只回傳合併後的值須另外儲存
>同理:difference & difference_update、intersection & intersection_update、symmetric_difference & symmetric_difference_update
2. **remove & discard**
- 差別:若刪除一個不存在於原集合的元素,remove會報錯;discard則不會
```python=
# remove
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.remove('AAA')
print(S)
```
```
輸出:
KeyError Traceback (most recent call last)
<ipython-input-67-43e44574d2dd> in <cell line: 4>()
2 S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
3
----> 4 S.remove('AAA')
5 print(S)
KeyError: 'AAA'
```
```python=
# discard
S = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'}
S.discard('AAA')
print(S)
# 輸出:{'Tuesday', 'Monday', 'Thursday', 'Friday', 'Wednesday'}
```
3. 只有intersection可同時比較2個以上的集合
4. pop的隨機,是取決於seed,並非真正的隨機
[參考連結](https://steam.oxxostudio.tw/category/python/library/random.html)
:::
---
## 練習題
**Zerojudge**
[**連結**](https://zerojudge.tw/)
---
## 補充資料
**推薦網站:**[**W3Schools**](https://www.w3schools.com/)