---
# System prepended metadata

title: 【Python基礎教學】資料型態函數及方法（下）【part-9】
tags: [Python, 程式語言]

---

【Python基礎教學】資料型態函數及方法（下）【part-9】
===

目錄（Table of Contents）

[TOC]

---

哈囉大家好，很感謝你點進本文章，我是一名高中生，是電腦社社團的社長，由於我並不是 Python 這方面非常精通的專家，所以若文章有些錯誤請見諒，也可向我指正錯誤。另外本文章的用意是作為電腦社社團的教材使用而編寫的。

上次我們講到了 Number、String 更深入的用法，以及介紹他們特有的函數及方法。本篇教學【part 9】繼續延續上篇尚未講完的資料型態：list、tuple、set。

列表（List）
---

列表，也可稱為串列（List），說到列表，就讓我們來談及一個概念：序列（Sequence）

序列，是 Python 中最基本的資料結構，是 Python 中的一種內建型態（built-in type）。

> 內建型態就是建構在　Python Interpreter（Python 直譯器）裡面的型態

簡單來說，內建型態就是在 Python 中不需要額外安裝模組或套件，就能直接使用的資料型態，如同：Number、String 等等。

序列中的每個值都具有對應的位置值，稱為索引（index）。所有索引的開頭都預設為 0 開始，慢慢疊加上去，如：0、1、2、3 等。

在 Python 中，內建 6 個序列的內建型態，而最常見的就是列表（list）跟元組（tuple）。

### 定義（definition）
---

列表（list）是一種常見的內建資料結構。列表是一種有序的集合，可以包含不同資料型態的元素（element）。列表的元素是可變的（mutable），這表示你可以任意修改列表之內容，例如增加、刪除或修改元素。列表使用中括號 [] 定義，元素之間以逗號分隔。

以左右兩個中括號 []，括起來，裡面可以放入任意不同的資料型態，不受限，也可以在列表裡面放入一個列表，這稱為二維列表。

不過需要注意的是，在列表內每一個資料型態（元素）之間需要以逗號作為分隔，範例如下所示：

```python=
['s', 1234, 0.234324, [1,2,3,4,5,6]] # 這是一個列表

list1 = [1,2,3,4]  # 將列表存入變數 list1 當中
```

註：不建議使用 list 作為變數名稱，因為 list() 是內建函數，能使資料型態變成列表（顯式轉換），如果同名的話可能導致函數失效。

### 運算（operation）
---

| statement | 結果 | 描述 |
| -------- | -------- | -------- |
| len([1, 2, 3]) | 3 | 計算列表中的元素總和 |
| [1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 以運算子 "+" 組合兩個列表 |
| ['Hi!'] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 以運算子 "*" 重複輸出同一個列表 |
| 3 in [1, 2, 3] | True | 以運算子 "in" 檢查 3 是否在列表裡面 |

列表中所進行的運算與字串運算十分相似，不過本小節用意主要還是幫大家複習一些運算子的應用。

### 巢狀列表（nested-list）
---

簡單來說跟巢狀迴圈是一樣的概念，就是列表裡面在放一個列表，如下所示：

```python=
[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
# 註：以上是二維列表。
```

利用上述列表，我們可以結合巢狀迴圈這麼應用：

```python=
a = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]
for i in range(len(a)):
    for j in range(0,5):
        print(a[i][j])
```

輸出結果：

```python=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
```

範例解析：

在變數 a 中，我們先將第一層做一個拆解：

首先 a[0] = [1,2,3,4,5]，為一個列表，然後我們再進入第二層，也就是再加上一個中括號：

a[0][0] = 1，就能夠得到第一層中那個列表，那個第一層列表中的第一個元素的值。

之後就以此類推：a[0][1] = 2 等等...

我們看到 for 迴圈的地方，一樣先拆解第一層的代碼塊：

for i in range(len(a)) 的意思就是將 range(len(a)) 做迭代，而 len(a) 就是第一層的元素總和，也就是那個[1,2,3,4,5], [6,7,8,9,10], [11,12,13,14,15]，總共有三個，所以 range(len(a)) 就會將變數 i 從 0 遞增到 2，總共迭代三次。

首先第一次，我們會直接進入到 for 迴圈的第二層結構：for j in range(0,5)

這個代表說會迭代 0 ~ 4，並且存入變數 j 進行遞增。

第二層的第一次迭代（for j in range(0,5)）：

a[0][0]

第二層的第二次迭代（for j in range(0,5)）：

a[0][1]

...

第二層的第五次迭代（for j in range(0,5)）：

a[0][4]

目前的狀況是，我們處於第一層的 for 迴圈中的第一次迭代，然而第一層的 for 迴圈裡面，還具有一層 for 迴圈，我們暫且稱他為第二層的 for 迴圈，而又在第二層 for 迴圈裡面，我們會迭代五次（從 0 ~ 4）。

因為還在第一層 for 迴圈的第一次迭代這個狀態中，所以 i 值並不會改變，從頭到尾都是 0，因此我們便可以從 [1,2,3,4,5] 裡面不斷印出數字出來。

依照這個原理，在當第二層 for 迴圈結束後，便會進回到第一層 for 迴圈進行下一次的迭代，以此類推。

巢狀列表在我們 Python 基本資料結構裡面的實作是非常重要的一環，所以才會將範例做一個解析，希望各位能夠清晰明瞭。

:::success
快速整理！
巢狀列表：列表裡面的元素之資料型態還是列表。`[[1,2,3], [1,2,3], [1,2,3]]`
巢狀迴圈：迴圈之下還有一個迴圈。

```python=
for i in range(10):
    for j in range(5):
        pass
```

以上是巢狀迴圈的範例，i = 1 時，j 會跑 5 次，i = 2 時，j 還是會跑 5 次，所以每次 i 變動時，j 就會從 0 ~ 4 遞增，執行 5 次。總體會執行 50 次。
:::

### 列表函數及方法（functions / methods）
---

| Number | 函數 |
| -------- | -------- |
| 1 | **len(list)**：計算列表元素總和 |
| 2 | **max(list)**：回傳列表的最大值 |
| 3 | **min(list)**：回傳列表的最小值 |
| 4 | **list(seq)**：將序列轉換成列表資料型態 |

| Number | 方法 |
| -------- | -------- |
| 1 | **list.append(obj)**：在列表尾端新增新的物件 |
| 2 | **list.count(obj)**：計算某元素在列表中出現的次數 |
| 3 | **list.extend(seq)**：在列表末尾一次性追加另一個序列中的多個值（用新列表擴展原來的列表） |
| 4 | **list.index(obj)**：從列表中找出某個值第一個匹配項的索引位置 |
| 5 | **list.insert(index, obj)**：將物件插入列表中，index 為欲插入該列表中的元素索引值，obj 為物件 |
| 6 | **list.pop([index=-1])**：移除列表中的一個元素，索引預設為列表的末端（-1） |
| 7 | **list.remove(obj)**：移除列表中某個值（obj）的第一個匹配項 -> 在括號內輸入指定值，python 會自動尋找指定刪除的值並刪除它，但輸入列表中不存在的值會 error |
| 8 | **list.reverse()**：反轉列表的元素索引值 |
| 9 | **list.sort(key=None, reverse=False)**：對列表進行排序，若 reverse=False，則排序由小到大，否則反之。 |
| 9 | **list.clear()**：清空整個列表 |
| 10 | **list.copy()**：複製列表 |

以下是一個練習範例：

```python=
my_list = []

# append() 方法：在列表最末端中(意即從 index = -1)新增元素
my_list.append(10)
my_list.append(5)
my_list.append(8)

print("原始列表：", my_list)  # [10, 5, 8]

# len() 函數計算列表中的元素總和
length = len(my_list)
print("列表長度：", length)  # 3

# max() 函數回傳列表中的最大值
max_value = max(my_list)
print("列表中的最大值：", max_value)  # 10

# min() 函數回傳列表中的最小值
min_value = min(my_list)
print("列表中的最小值：", min_value)  # 5

# sort() 方法：對列表進行升序排序
my_list.sort()
print("排序後的列表：", my_list)  # [5, 8, 10]

# reverse() 方法：反轉列表
my_list.reverse()
print("反轉後的列表：", my_list)  # [10, 8, 5]

# count() 方法：計算某個元素在列表中出現的次數
count_10 = my_list.count(10)
print("列表中數字 10 出現的次數：", count_10)  # 1

# pop() 方法：移除列表最末端（意即 index = -1）的元素
removed_element = my_list.pop()
print("移除的元素：", removed_element)  # 5
print("移除後的列表：", my_list)  # [10, 8]

# clear() 方法：清空列表
my_list.clear()
print("清空後的列表：", my_list)  # []
```

元組（Tuple）
---

在 Python 中，元組與列表的用法類似，但差異之處就在於元組的值是不能夠進行修改的。

不知道各位有沒有在 C 語言中學過常數（Constant）這個概念，如有學過，那麼你只要將這概念投射到元組上即可，把它想成是一個常數版本的陣列（C 語言中，列表的功用和陣列相似（arrays），可以把陣列想成是運算速度很快的列表）。

要使用元組這個資料型態，須以小括號 () 括起來，不同於列表的中括號 []。

元組的創建基本上與列表相同，加入相應元素即可：

`tup1 = (1,2,3,4,5)`

創建一個空元組可這樣寫：

`tup1 = ()`

在這裡我們需要注意的是：元組若只有一個元素，必須加上一個逗號，否則會被當成另一個資料型態使用。

註：以下範例環境在 IDLE Shell 中進行。

```python=
>>> tup1 = (1)
>>> type(tup1)     # 不加逗號，型態為整數（int）
<class 'int'>

>>> tup1 = (1,)
>>> type(tup1)     # 加上逗號，型態為元組（tuple）
<class 'tuple'>
```

另外值得一提的是，元組不加上小括號也是能夠成立的：

```python=
>>> tup1 = "a", "b", "c", "d"
>>> type(tup1)
<class 'tuple'>

>>> tup2 = 4, 3, 2, 1
>>> type(tup2)
<class 'tuple'>
```

同樣地，元組的索引一樣是從 0 開始，也可以進行截取、組合。

由於前面已經敘述過多次截取、組合的內容，於是本節便不再詳細介紹。

另外使用元組的優點具以下三點：

1. 讀取速度比列表快
2. 占用的空間較少
3. 資料更為安全（因為不能資料被修改）

### 強制修改元組內容
---

> 使用串列 list 存取 tuple 資料，修改資料後，再轉換為新的 tuple ( 注意，雖然變數名稱相同，但兩個 tuple 是完全不同的 )。

```python=
a = ('apple','banana','orange')
b = list(a)
b.append('grap')
a = tuple(b)
print(a)   # ('apple', 'banana', 'orange', 'grap')
```

說明兩個 tuple 是完全不同的，是因為兩者之間（被修改前與修改後的變數 a）的數值（value）並未完全相同，且使用 id() 函數得知，兩者的記憶體位址是不一樣的：

```python=
>>> a = ('apple','banana','orange')
>>> id(a)
>>> 2080064319872

>>> b = list(a)
>>> b.append('grap')
>>> a = tuple(b)
>>> id(a)
>>> 2080059268272 #記憶體位址不一樣
```

### 運算（operation）
---

1. **len(tuple)**：計算元組總共所有的元素
2. **(1,2,3) + (4,5,6)**：兩元組可用 `+` 號連結。
3. **元組可以用 `*` 號來進行重複複製。**

那元組的運算基本上與列表都差不多，大概就是這樣而已。

至於元組的索引及擷取方式，其實也跟列表是一樣的，如下所示：

```python=
>>> a = (1,2,3,4,5,6,7)
>>> print(a[0])
1

>>> print(a[:0])
()

>>> print(a[:-1])
(1, 2, 3, 4, 5, 6)
```

集合（Set）
---

> 集合 ( set ) 就像是「只有鍵，沒有值」的字典，一個集合裡所有的鍵都不會重複，因為集合不會包含重複的資料的特性，常用來進行去除重複的字元、或判斷元素間是否有交集、聯集或差集之類的關聯性。

總之，集合是一個無序不重複的元素序列。

集合中的元素不會重複，並且可以進行交集、並集、差集等等的操作。

Python 中，要創建一個集合，與列表、元組不同的是，我們要使用大括號 {} 來表示一個集合，至於元素的部分我們就不再贅述，因為基本上都是一樣的，集合的定義如下所示：

```python=
parame = {value01, value02,...}
# or like this
set(value)
```

以下是一個範例（出自菜鳥教程）：

```python=
set1 = {1, 2, 3, 4}           # 直接使用大括號創造集合
set2 = set([4, 5, 6, 7])      # 使用 set() 函數從列表創建集合
```

> **注意：建立一個空集合必須用 set() 而不是 {}，因為 {} 是用來建立一個空字典。**

不過作者在這邊建議：如果要建立一個集合的話就使用 set() 函數建立，否則很容易跟字典混淆。

:::success
快速整理！
集合（set）：無序且「不重複（很重要）」的資料集合，如下：

```python=
>>> set1 = set([1,2,3,4,5,6,2,2,3])
>>> print(set1)
{1, 2, 3, 4, 5, 6}
```

無序（Unordered）：集合中的元素沒有特定的順序，表示每次存取元素時，其排列順序可能會有所不同。
:::

### 運算（operation）
---

**s.add(x)**：將元素 x 新增到集合 s 當中，範例如下所示：

```python=
>>> a = set((1,2,3,4))
>>> a.add(5)
>>> print(a)
{1, 2, 3, 4, 5}
```

> 還有一個方法，也可以加入元素，且參數可以是列表，元組，字典等，語法格式如下：

**s.update(x)**：同 s.add(x)，不過 x 可以有多個。

```python=
>>> a = set((1,2,3,4))
>>> a.update({5,6,7,8})
>>> print(a)
{1, 2, 3, 4, 5, 6, 7, 8}
```

```python=
>>> b = set((9,10,11,12,13))
>>> b.update([14,15,16,17,18])
>>> print(b)
{9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
```

**s.remove(x)**：將元素 x 從集合 s 移除，如果元素不存在，則會發生錯誤。

```python=
>>> a = set((1,2,3,4))
>>> a.remove(1)
>>> print(a)
{2, 3, 4}

>>> a.remove(0) # 因為在集合 a 當中找不到 0 元素存在，所以報錯。
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    a.remove(0)
KeyError: 0
```

> 另外還有一個方法也是移除集合中的元素，且如果元素不存在，不會發生錯誤。格式如下圖所示：

**s.discard(x)**：同 s.remove(x)，不過當找不到元素 x 時不會發生錯誤。

```python=
>>> a = set((1,2,3,4))
>>> a.discard(0) # 不會發生錯誤
```

> 我們也可以設定隨機刪除集合中的一個元素，語法格式如下：

**s.pop()**：隨機刪除集合中的一個元素。

以上這些都是針對集合（Set）的新增、刪除的方法介紹，待後續將列出完整的方法表格。

### 交集、聯集、差集、對稱差集
---

![image](https://hackmd.io/_uploads/H1o994NkR.png)

圖源：[集合 set - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/set.html)

這個交集、聯集呢，跟我們在數學上學的是一樣的，只是這個概念被挪到程式語言上來用而已。

交集（數學上）：A ∩ B（包含集合 A 與集合 B 共同擁有的元素）
聯集（數學上）：A U B（包含集合 A 跟集合 B 的所有元素）
差集（數學上）：A - B（包含集合 A，但不包含集合 B 的所有元素）
對稱差集（數學上）：A△B（不包含集合 A 與集合 B 共同擁有的元素，也就是說 A ∩ B 以外的所有元素。）

說完數學上的意義，接下來讓我們回到程式語言的部分：

| 集合 | 方法 | 運算子 |
| -------- | -------- | -------- |
| 交集 | a.intersection(b) | a&b |
| 聯集 | a.union(b) | a｜b |
| 差集 | a.difference(b) | a-b |
| 對稱差集 | a.symmetric_difference(b) | a^b |

```python=
a = {1,2,3,4,5}
b = {3,4,5,6,7}

# 交集
print(a.intersection(b))   # {3, 4, 5}
print(a&b)                 # {3, 4, 5}
# 聯集
print(a.union(b))          # {1, 2, 3, 4, 5, 6, 7}
print(a|b)                 # {1, 2, 3, 4, 5, 6, 7}
# 差集
print(a.difference(b))     # {1, 2}
print(a-b)                 # {1, 2}
# 對稱差集
print(a.symmetric_difference(b))  # {1, 2, 6, 7}
print(a^b)                        # {1, 2, 6, 7}
```

以上範例、圖表源自於：[集合 set - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/set.html)

### 集合方法（methods）
---

| 方法（Method） | 敘述（description） |
| -------- | -------- |
| add() | 為集合新增元素 |
| clear() | 移除集合中的所有元素 |
| copy() | 複製一個集合 |
| difference() | 差集：回傳多個集合的差集 |
| difference_update() | 差集：移除集合中的元素，該元素在指定的集合也存在 |
| discard() | 刪除集合中指定的元素 |
| intersection() | 交集：回傳集合的交集 |
| intersection_update() | 交集：回傳集合的交集 |
| isdisjoint() | 判斷兩個集合是否包含相同的元素，如果沒有回傳 True，否則回傳 False |
| issubset() | 判斷指定集合是否為該方法參數集合的子集 |
| issuperset() | 判斷方法的參數集合是否為指定集合的子集 |
| pop() | 隨機移除元素 |
| remove() | 移除指定元素 |
| symmetric_difference() | 對稱差集：回傳兩個集合中不重複的元素集合 |
| symmetric_difference_update() | 對稱差集：移除目前集合中在另外一個指定集合相同的元素，並將另一個指定集合中不同的元素插入到目前集合中 |
| union() | 聯集：回傳兩個集合的聯集 |
| update() | 為集合添加元素 |
| len() | 計算集合元素個數 |

表格來源：[Python3 集合 | 菜鳥教程](https://www.runoob.com/python3/python3-set.html)

以下是一個練習範例：

```python=
# 建立兩個集合
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}

# add(): 為集合新增元素
set1.add(9)
print("After add(9):", set1)

# clear(): 移除集合中的所有元素
temp_set = set1.copy()
temp_set.clear()
print("After clear():", temp_set)

# copy(): 複製一個集合
set_copy = set1.copy()
print("Copy of set1:", set_copy)

# difference(): 差集，回傳多個集合的差集
diff_set = set1.difference(set2)
print("Difference between set1 and set2:", diff_set)

# difference_update(): 移除集合中的元素，該元素在指定的集合也存在
set1.difference_update(set2)
print("After difference_update(set2):", set1)

# discard(): 刪除集合中指定的元素
set1.discard(9)
print("After discard(9):", set1)

# intersection(): 交集，回傳集合的交集
set_inter = set1.intersection(set2)
print("Intersection of set1 and set2:", set_inter)

# intersection_update(): 交集，回傳集合的交集
set1.intersection_update(set2)
print("After intersection_update(set2):", set1)

# isdisjoint(): 判斷兩個集合是否包含相同的元素
disjoint_result = set1.isdisjoint(set2)
print("Are set1 and set2 disjoint?:", disjoint_result)

# issubset(): 判斷指定集合是否為該方法參數集合的子集
subset_result = set1.issubset(set2)
print("Is set1 a subset of set2?:", subset_result)

# issuperset(): 判斷方法的參數集合是否為指定集合的子集
superset_result = set2.issuperset(set1)
print("Is set2 a superset of set1?:", superset_result)

# pop(): 隨機移除元素
popped_element = set1.pop()
print("Element popped from set1:", popped_element)
print("After pop():", set1)

# remove(): 移除指定元素
set2.remove(8)
print("After remove(8) from set2:", set2)

# symmetric_difference(): 對稱差集，回傳兩個集合中不重複的元素集合
sym_diff = set1.symmetric_difference(set2)
print("Symmetric difference between set1 and set2:", sym_diff)

# symmetric_difference_update(): 對稱差集
set1.symmetric_difference_update(set2)
print("After symmetric_difference_update(set2):", set1)

# union(): 聯集，回傳兩個集合的聯集
union_set = set1.union(set2)
print("Union of set1 and set2:", union_set)

# update(): 為集合添加元素
set1.update({10, 11})
print("After update({10, 11}):", set1)

# len(): 計算集合元素個數
set_length = len(set1)
print("Length of set1:", set_length)
```

總結
---

| 相異處 | 列表（List） | 元組（Tuple） | 集合（Set） |
| -------- | -------- | -------- | -------- |
| 有序 or 無序 | 有序 | 有序 | 無序 |
| 可變 or 不可變 | 可變（mutable） | 不可變（immutable） | 集合本身是可變的，但其元素不可變。 |
| 定義 | 兩個中括號 `[]`，裡面放元素（element），元素間以逗點相隔 | 兩個小括號 `()`，裡面放元素（element），元素間以逗點相隔 | 兩個大括號 `{}`，裡面放元素（element），元素間以逗點相隔，但是元素並沒有所謂鍵值對，又稱沒有鍵值對的字典。或是可用函數 set() 建立集合。 |
| 元素資料型態 | 任意 | 任意 | 不可變物件（immutable） |
| 元素重複性 | 可重複 | 可重複 | 不重複 |
| 記憶體消耗 | 相對較高 | 相對較低 | 相對較低 |
| 適用情況 | 需要有序、可變的資料結構，如佇列（Queue）、堆疊（Stack）等 | 需要固定資料的情況，如函數參數、回傳值等 | 需要快速查找、不重複元素的情況，如集合運算、去重複等 |

以下是一些參考資料～

參考資料
===

[Python3 列表 | 菜鳥教程](https://www.runoob.com/python3/python3-list.html)

[Python3 元組 | 菜鳥教程](https://www.runoob.com/python3/python3-tuple.html)

[Python3 List sort()方法 | 菜鳥教程](https://www.runoob.com/python3/python3-att-list-sort.html)

[Python序列（Sequence） - 小宇2 - 博客園](https://www.cnblogs.com/livingintruth/p/3254654.html)

[元組 ( 數組 ) tuple - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/tuple.html)

[集合 set - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/basic/set.html)

[Python3 集合 | 菜鳥教程](https://www.runoob.com/python3/python3-set.html)

[對稱差 - 維基百科，自由的百科全書](https://zh.wikipedia.org/zh-tw/%E5%AF%B9%E7%A7%B0%E5%B7%AE)