Python Tuple 元組:不可變序列的特性與應用

Python Tuple 元組是以小括號 () 建立的不可變序列,外觀與 List 相似,卻有一個關鍵差異:一旦建立就無法修改。本文涵蓋 Tuple 的建立語法、索引與切片、count 與 index 方法、與 List 的比較,以及 Tuple 在元組解包(Tuple Unpacking)、函數多值回傳、*args 彈性參數等進階場景的核心應用,讓你徹底理解為什麼 Python 需要 Tuple。

Cinematic visualization of Python tuple as sealed stone tablets glowing with amber runes, immutable carved symbols arranged in sequence, deep alchemical workshop with forge light, dramatic shadows, dark fantasy atmosphere, 16:9

什麼是 Tuple 元組?

Tuple(元組)是 Python 的內建序列型別,使用小括號 () 建立,每個元素以逗號分隔。它的結構與 List 幾乎相同,支援索引、切片、迭代——但有一個根本差異:Tuple 是不可變的(immutable),建立後不能新增、刪除或修改任何元素。

可以把 Tuple 想像成刻在石板上的資料:List 是可以隨時改寫的白板,Tuple 則是一旦刻好就永久存在的石碑。這種特性讓 Tuple 天生適合儲存「不該被意外更改」的資料,例如 RGB 顏色值、座標點、或函數的多值回傳。

Python 的 dict.items()enumerate()zip() 等大量內建函數都以 Tuple 形式回傳資料,因此即使你目前用到 Tuple 不多,理解它也是掌握進階 Python 的必要基礎。

核心語法:建立與存取

# === 建立 Tuple ===
# 方式一:小括號 + 逗號
color = (255, 128, 0)        # RGB 橘色
point = (10.5, -3.2)         # 座標

# 方式二:省略括號(僅靠逗號)
a, b = 1, 2                  # 本質上是 Tuple 拆包

# 建立單一元素 Tuple(注意必須有尾端逗號!)
single = (42,)               # 這才是 Tuple
not_tuple = (42)             # ❌ 這只是 int,加了括號沒用

# 建立空 Tuple
empty = ()

# 用 tuple() 轉換其他序列
from_list = tuple([1, 2, 3])  # (1, 2, 3)
print(type(color))            # 
單一元素 Tuple 必須在值後加上逗號:(42,)(42) 只是普通的整數加括號,並不是 Tuple。這是初學者最常犯的建立錯誤。
# === 索引、切片、長度 ===
piano = ('do', 're', 'mi', 'fa', 'sol', 'la', 'si')

print(piano[0])       # 'do'(正向索引)
print(piano[-1])      # 'si'(反向索引)
print(piano[2:5])     # ('mi', 'fa', 'sol')(切片)
print(len(piano))     # 7

# === Tuple 的兩個內建方法 ===
notes = ('do', 're', 'do', 'mi', 'do')

print(notes.count('do'))   # 3(計算出現次數)
print(notes.index('mi'))   # 3(回傳第一次出現的索引)
Tuple 只有 count()index() 兩個方法,遠少於 List 的眾多方法——這正是不可變性帶來的限制。你無法對 Tuple 使用 append()pop()sort() 等修改類方法。

規則與注意事項

規則 正確範例 錯誤範例
Tuple 不可修改元素(immutable) t = (1, 2, 3) 後直接使用 t[0] = 99 → TypeError
單一元素 Tuple 需加尾端逗號 t = (42,) t = (42) → 只是 int
可包含異質型別 t = ('Alice', 30, True) 無誤,但應保持資料語義一致
Tuple 可作為 Dict 的 Key(因可雜湊) d = {(0,0): '原點'} List 不可作為 Key → TypeError
Tuple 支援索引、切片、迭代 t[1:3]for x in t: 不支援 append()remove()

常見錯誤與防呆

錯誤一:嘗試修改 Tuple 元素

# ❌ 錯誤寫法(TypeError: 'tuple' object does not support item assignment)
color = (255, 128, 0)
color[0] = 100

# ✅ 正確做法:若需要修改,先轉為 List,改完再轉回
color_list = list(color)
color_list[0] = 100
color = tuple(color_list)
print(color)  # (100, 128, 0)

錯誤二:建立單一元素 Tuple 忘記加逗號

# ❌ 錯誤寫法(這不是 Tuple,只是 int)
t = (42)
print(type(t))  # 

# ✅ 正確寫法:加上尾端逗號
t = (42,)
print(type(t))  # 

錯誤三:元組解包數量不符

# ❌ 錯誤寫法(ValueError: too many values to unpack)
data = (1, 2, 3)
a, b = data      # 只有兩個變數,但 Tuple 有三個元素

# ✅ 正確寫法:變數數量對齊,或用 * 收集多餘值
a, b, c = data           # 完整解包
a, *rest = data          # a=1, rest=[2, 3]

進階用法

元組解包(Tuple Unpacking)

Tuple Unpacking 讓你一行就能將多個值分配給多個變數,是 Python 最優雅的特性之一,大量出現在迴圈迭代與函數回傳中。

# 基本解包:變數數量對應 Tuple 元素數
name, age, city = ('小明', 25, '新竹')
print(name)  # 小明
print(city)  # 新竹

# 用 * 收集剩餘元素
first, *middle, last = (10, 20, 30, 40, 50)
print(first)   # 10
print(middle)  # [20, 30, 40](注意:被收集為 List)
print(last)    # 50

# 搭配 for 迴圈:迭代含 Tuple 的 List(最常見場景)
stock_prices = [('AAPL', 175.5), ('TSLA', 250.0), ('GOOGL', 140.3)]
for ticker, price in stock_prices:
    print(f'{ticker}:{price} 元')

函數多值回傳

Python 函數的 return 後面跟多個值,實際上是回傳一個 Tuple。這讓函數能同時回傳多筆相關資料,搭配解包使用更加簡潔。

# 函數回傳多值,本質是回傳 Tuple
def get_minmax(numbers):
    return min(numbers), max(numbers)   # 等同 return (min(...), max(...))

data = [15, 3, 42, 7, 88, 1]
result = get_minmax(data)
print(result)         # (1, 88)
print(type(result))   # 

# 直接解包接收
low, high = get_minmax(data)
print(f'最小值:{low},最大值:{high}')

Tuple 作為字典 Key(可雜湊特性)

因為 Tuple 不可變,所以它是可雜湊的(hashable),可以當作字典的 Key。這在二維座標對應、複合索引等場景非常實用,而 List 完全做不到這一點。

# 用座標 Tuple 作為 Dict Key(量化策略:網格交易點位標記)
grid_map = {}
grid_map[(1, 2)] = '買入區間'
grid_map[(3, 4)] = '賣出區間'
grid_map[(0, 0)] = '原點觀察'

print(grid_map[(1, 2)])   # 買入區間

# enumerate() 回傳的就是 Tuple
for idx, val in enumerate(['a', 'b', 'c']):
    print(idx, val)        # 0 a / 1 b / 2 c

煉金坊小叮嚀

Tuple 是 Python 中最容易被初學者忽略的資料型別,但我在量化交易開發中幾乎天天用到它——尤其是解析 MT5 的行情資料時,很多欄位就是以 Tuple 格式回傳的。記住一個核心心法:當資料應該「不被改動」時,選 Tuple;當資料需要「動態增減」時,選 List。 另外,元組解包(Tuple Unpacking)是讓程式碼更簡潔的利器,for ticker, price in data: 這種寫法,一旦用熟了就再也回不去了。 搭配下一篇的 Set 集合,你對 Python 的四大基礎資料結構就全部融會貫通了!

張貼留言

較新的 較舊