本文 AI 產出,尚未審核

Python 課程 – 資料結構:清單(list)

主題:append / extend / insert / pop / remove


簡介

在 Python 中,清單(list) 是最常使用的可變序列資料型別。它支援動態增減元素、隨機存取以及多種內建方法,讓程式設計師能輕鬆處理各種集合資料。
本單元聚焦於五個最常見的清單操作:appendextendinsertpopremove。了解它們的差異與正確使用時機,對於寫出可讀性高、效能佳的程式碼至關重要。

為什麼要特別學習這五個方法?

  • appendextendinsert 負責 向清單寫入 資料。
  • popremove 則是 從清單刪除 資料的主要工具。
    正確選擇與搭配使用,能避免不必要的時間與記憶體開銷,並減少常見的錯誤(例如刪除錯誤的元素或產生意外的參照關係)。

核心概念

1. list.append(obj)

append 會把 單一物件 加到清單最尾端,操作是 原位(in‑place) 的,也就是說原本的清單會被直接修改,並不會回傳新清單。

# 範例 1:基本用法
fruits = ['apple', 'banana']
fruits.append('cherry')
print(fruits)   # ['apple', 'banana', 'cherry']

# 範例 2:加入另一個 list 本身(會變成子清單)
numbers = [1, 2, 3]
numbers.append([4, 5])
print(numbers)  # [1, 2, 3, [4, 5]]

小提醒append 只接受 一個 參數,若想一次加入多個元素,請改用 extend


2. list.extend(iterable)

extend 會把 可疊代物件(iterable) 中的每個元素逐一加入清單尾端,同樣是原位修改。這是 展開 另一個序列的最佳方式。

# 範例 3:將另一個 list 的元素展開加入
a = [1, 2]
b = [3, 4, 5]
a.extend(b)
print(a)        # [1, 2, 3, 4, 5]

# 範例 4:使用字串、集合或產生器
c = ['x', 'y']
c.extend('zpq')         # 字串會被視為字元序列
print(c)                # ['x', 'y', 'z', 'p', 'q']

d = set([10, 20])
c.extend(d)             # 集合的元素順序不保證
print(c)

為什麼 extend 常比多次 append 效率高?
每次 append 可能會觸發清單的重新配置(reallocation),而 extend 會一次性計算總長度,減少記憶體搬移的次數。


3. list.insert(index, obj)

insert 可以在 任意位置 插入單一物件。index 若超出範圍,會自動調整到最前或最後。

# 範例 5:在中間插入元素
colors = ['red', 'blue']
colors.insert(1, 'green')   # 在索引 1 前插入
print(colors)               # ['red', 'green', 'blue']

# 範例 6:負索引與超界插入
colors.insert(-1, 'yellow') # 插入到倒數第二個位置前
colors.insert(100, 'purple')# 超過長度,直接加到最後
print(colors)               # ['red', 'green', 'yellow', 'blue', 'purple']

注意insert 會把插入位置之後的所有元素往後搬移,若清單很長,頻繁使用會產生 O(n) 的時間成本。


4. list.pop([index])

pop移除並回傳 指定位置的元素,預設是最後一個(index=-1)。如果清單為空,會拋出 IndexError

# 範例 7:彈出最後一個元素
stack = [10, 20, 30]
last = stack.pop()
print(last)    # 30
print(stack)   # [10, 20]

# 範例 8:彈出任意位置
stack.insert(0, 5)
mid = stack.pop(1)   # 移除索引 1 的元素 (10)
print(mid)           # 10
print(stack)         # [5, 20]

實務技巧pop 常用於 堆疊(stack) 的實作,因為它只涉及尾端操作,時間複雜度為 O(1)


5. list.remove(value)

remove 會搜尋 第一個value 相等的元素並將其刪除,若找不到則拋出 ValueError。它不回傳被刪除的項目。

# 範例 9:刪除指定值
items = ['a', 'b', 'c', 'b']
items.remove('b')      # 只會刪除第一個 'b'
print(items)           # ['a', 'c', 'b']

# 範例 10:錯誤處理
try:
    items.remove('x')
except ValueError:
    print('元素不存在!')

提醒remove 會遍歷整個清單直到找到目標,最壞情況下是 O(n)。若需要大量刪除,考慮使用 列表推導式集合(set) 來加速。


常見陷阱與最佳實踐

陷阱 說明 建議做法
append 當成 extend list.append([1,2]) 會產生子清單,非預期的結構。 若要一次加入多個元素,使用 extend;若真的需要子清單,才用 append
在迴圈中同時 remove 直接遍歷清單並刪除會導致索引錯位,部分元素會被跳過。 使用 倒序迴圈 (for i in range(len(lst)-1, -1, -1)) 或 列表推導式 產生新清單。
大量 insert 到前端 每次插入都會搬移整個清單,效能低下。 若需要頻繁在頭部操作,可改用 collections.deque
忘記檢查空清單再 pop 空清單直接 pop() 會拋 IndexError 在彈出前使用 if mylist: 判斷或捕獲例外。
remove 失敗未捕獲 找不到元素時會中斷程式。 先用 if value in mylist: 判斷,或使用 try/except

最佳實踐小結

  1. 選對方法append 單一、extend 多個、insert 指定位置。
  2. 盡量避免在大清單前端插入或刪除,改用 deque 或重新建構清單。
  3. 使用例外處理 或事前檢查,提升程式的魯棒性。
  4. 記得操作是原位的,若需要保留原始清單,先 copy()

實際應用場景

1. 堆疊(Stack)實作

class Stack:
    def __init__(self):
        self._data = []

    def push(self, item):
        self._data.append(item)   # O(1)

    def pop(self):
        if not self._data:
            raise IndexError('pop from empty stack')
        return self._data.pop()   # O(1)

    def peek(self):
        return self._data[-1] if self._data else None

2. 合併多筆資料

# 從多個 CSV 檔讀取資料,合併成單一清單
all_rows = []
for filename in ['a.csv', 'b.csv', 'c.csv']:
    with open(filename) as f:
        rows = f.read().splitlines()
        all_rows.extend(rows)   # 一次展開加入

3. 事件排程(Queue)— 使用 pop(0)(不建議) vs deque

from collections import deque

queue = deque()
queue.append('task1')
queue.append('task2')
first = queue.popleft()   # O(1) 取出最前面的任務

若改用 list.pop(0),每次都會搬移整個清單,效能會退化。

4. 清除重複或不需要的元素

raw = ['apple', 'banana', 'apple', 'cherry', 'banana']
# 移除所有出現超過一次的元素
unique = []
for item in raw:
    if item not in unique:
        unique.append(item)   # 使用 append 建立新清單
print(unique)   # ['apple', 'banana', 'cherry']

總結

本單元針對 appendextendinsertpopremove 五個清單方法進行了深入說明與實作範例。掌握它們的行為差異與效能特性,能讓你:

  • 正確選擇 資料寫入刪除 的方式,避免不必要的時間與記憶體浪費。
  • 在實務開發中以 堆疊、佇列、資料合併 等常見情境快速構築穩定的程式邏輯。
  • 識別常見陷阱,運用例外處理與最佳實踐提升程式的可讀性與魯棒性。

只要熟練這幾個方法,清單的使用將變得得心應手,為日後學習更進階的資料結構(如 dictsetdeque)奠定堅實基礎。祝你在 Python 的世界裡玩得開心、寫得更好!