引言:整理我們的數據

歡迎來到數據結構(Data Structures)的學習筆記!在電腦編程中,我們經常要處理各種資訊——例如遊戲中的最高得分、班冊上的學生姓名,或是購物車裏的商品清單。如果每件物品都要為它創建一個全新的變量(Variable),你的程式碼很快就會變得非常混亂且難以管理。

這正是數據結構大派用場的時候!在這一章中,你將會學到如何使用列表(Lists)、陣列(Arrays)和表格(Tables),將大量數據歸納在同一個名稱之下。如果一開始覺得有點陌生或深奧,不用擔心——我們會一步一步為你拆解每個概念!

重點提示:數據結構是編程中專門用來存放、組織和管理多個數據項目的容器,只需一個識別名稱(變量名)就能輕鬆調用。


1. 甚麼是列表(Lists)和陣列(Arrays)?

想像一下學校裏一整排編了號碼的儲物櫃。每個儲物櫃都可以放一件物品,而整排儲物櫃共享一個共同名稱,例如 Year7Lockers(中一級儲物櫃)。這正是編程中列表和陣列的運作方式!

陣列(Arrays)

• 在電腦科學理論中,陣列是一種線性數據集合,所有項目在記憶體中都是緊鄰存放的。
相同數據類型:傳統上,一個陣列內的所有項目必須是完全相同的數據類型(例如只能全都是整數,或全都是文本字串)。
固定大小:經典的靜態陣列在創建時就已經確定了固定大小,之後不能隨意更改。

列表(Lists)

列表是一組有序的數據項目序列。
動態大小:與靜態陣列不同,在像 Python 這樣的文字編程語言中,當程式運行時,你可以隨時加入或刪除項目,列表的大小會自動增減。
混合數據類型:列表可以同時儲存不同類型的數據(例如數字、文字和小數混在一起)。

生活比喻:不妨把靜態陣列想像成一個雞蛋盒(格子數量固定,而且只能放雞蛋);而列表就像一個購物袋(你可以隨時放入或取出不同種類的物品!)。

重點提示:在 Python(初中 KS3 階段最常使用的文字編程語言)中,我們使用方括號 []列表來儲存有序的數據序列。


2. 認識索引(從零開始的黃金法則!)

要從列表或陣列中選取特定的項目,電腦會使用一個稱為索引(Index,複數為 Indices)的數字標籤。

索引的黃金法則:從零(0)開始!

在大多數編程語言中,計數並不是由 \(1\) 開始,而是從 \(0\) 開始!這就是著名的從零開始索引(Zero-based indexing)。

讓我們來看一個水果列表的例子:
fruits = ["apple", "banana", "cherry", "date"]

• 第一個項目("apple")位於索引 \(0\)fruits[0]
• 第二個項目("banana")位於索引 \(1\)fruits[1]
• 第三個項目("cherry")位於索引 \(2\)fruits[2]
• 第四個項目("date")位於索引 \(3\)fruits[3]

你知道嗎?如果一個列表包含 \(n\) 個項目,最後一個項目的索引必定是 \(n - 1\)。例如在我們這個有 \(4\) 種水果的列表中,最後一個項目的索引就是 \(4 - 1 = 3\)。

重點提示:請時刻謹記,任何列表或陣列中的第一個項目,其索引都是 \(0\),而不是 \(1\)。


3. 列表的基本操作

創建列表後,你可以執行幾種基本操作來查看、修改、新增或刪除其中的項目。

1. 創建列表

我們把各個項目放在方括號 [] 內,並用逗號分隔,就能建立一個列表:
shopping_list = ["bread", "milk", "cheese"]

2. 讀取與更新項目

讀取項目:要查看某個項目,寫出列表名稱並在方括號內加上索引即可。
print(shopping_list[1]) → 顯示 "milk"
更新/覆寫項目:你可以透過為特定索引賦予新值,來替換原本的項目。
shopping_list[0] = "bagel" → 把 "bread" 改為 "bagel"

3. 新增項目(Append 和 Insert)

附加(Append):在列表的最末尾添加一個新項目。
shopping_list.append("eggs") → 列表變成 ["bagel", "milk", "cheese", "eggs"]
插入(Insert):在指定的索引位置插入新項目,並將後面的項目全部向後推移。
shopping_list.insert(1, "butter") → 把 "butter" 放在索引 \(1\) 的位置

4. 刪除項目

按數值刪除:尋找並刪除列表中首次出現的特定數值。
shopping_list.remove("milk") → 搜尋 "milk" 並將它刪除。
按索引刪除:使用 del.pop() 刪除特定位置的項目。
del shopping_list[0]shopping_list.pop(0) → 刪除位於索引 \(0\) 的項目。

5. 獲取列表長度

使用 len() 函數可以找出列表中目前有多少個項目。
len(shopping_list) → 以整數形式返回項目總數。

6. 遍歷(用循環逐一檢查列表)

遍歷(Traversal)是指使用循環(Loop)將列表中的每個項目逐一走訪一遍。

按項目循環:
for item in shopping_list:
    print(item)

按索引循環:
for i in range(len(shopping_list)):
    print(shopping_list[i])

重點提示:使用 .append() 在末尾添加、.insert() 在指定位置插入、.remove() 按值刪除,以及 len() 檢查列表大小。


4. 表格:二維列表與二維陣列

有時候,數據需要整理成由(Rows,即橫行)和(Columns,即直行)組成的網格,就像試算表、戲院座位表或井字過三關棋盤一樣。這稱為表格二維陣列(2D Array)或二維列表(2D List,即列表中包含列表!)。

二維列表在程式碼中的樣子

讓我們看看代表遊戲棋盤的 \(3 \times 3\) 網格:
board = [
    ["X", "O", "X"],   # 第 0 列 (Row 0)
    ["O", "X", "O"],   # 第 1 列 (Row 1)
    ["O", "O", "X"]    # 第 2 列 (Row 2)
]

讀取二維表格中的元素

要在二維數據結構中精確定位一個項目,必須在方括號內提供兩個索引數字:[列索引][欄索引](即 [row_index][column_index])。

board[0][0] 代表第 \(0\) 列、第 \(0\) 欄"X"
board[0][1] 代表第 \(0\) 列、第 \(1\) 欄"O"
board[2][1] 代表第 \(2\) 列、第 \(1\) 欄"O"

記憶小貼士:請記住 RC 原則(就像控車 Remote Control,或者先 Row 後 Column)。「列」(橫行)在先,「欄」(直行)在後!

重點提示:表格或二維陣列是一個「列表中的列表」,透過座標格式 table[row][column] 讀取,索引同樣由 \(0\) 開始計算。


5. 常見陷阱與易犯錯誤

以下是同學們在處理數據結構時最常犯的錯誤——看看如何避開它們吧!

「差一錯誤」(Off-by-One Error):嘗試在一個只有 \(3\) 個項目的列表中讀取索引 \(3\)。由於索引範圍是 \(0\) 到 \(2\),索取索引 \(3\) 會導致 IndexError: list index out of range(索引超出範圍錯誤)。
意外覆寫整個列表:如果你寫了 my_list = "apple",你就會把整個列表替換成單一個詞語!要添加項目,請使用 my_list.append("apple");要替換特定項目,請使用 my_list[0] = "apple"
混淆列與欄的順序:寫成了 grid[column][row] 而不是 grid[row][column]。記住你的 RC 遙控車法則:先「列」(Row)後「欄」(Column)!
按數值還是按索引刪除:想刪除第一個項目時卻誤用了 list.remove(0).remove(0) 會在列表中搜尋數字 \(0\) 並將其刪除。若要按位置刪除,應使用 del list[0]list.pop(0)


6. 快速溫習清單

用這份清單快速自我檢測一下你的理解程度:

數據結構(Data Structure):用來儲存和組織多個數據值的專用容器。
陣列(Array):固定大小的線性結構,傳統上存放相同數據類型的項目。
列表(List):動態且有序的項目序列,使用方括號 [] 包裹。
從零開始索引(Zero-Based Indexing):第一個項目的索引是 \(0\),最後一個項目的索引是 \(n - 1\)
表格/二維陣列/二維列表(Table / 2D List):由列和欄組成的網格,以 [列][欄] 形式讀取。
重要方法(Methods):.append() 在末尾添加;.insert() 在指定索引插入;.remove() 按值刪除;len() 計算總數量。