本文 AI 產出,尚未審核

Python 課程 ── 運算子(Operators)

主題:指派運算子(=, +=, -=, …)


簡介

在程式語言中,**指派(assignment)**是最基礎、也是最常見的操作之一。它負責把資料(值)存入變數,讓程式的後續邏輯可以使用與修改這些資料。Python 提供了多種指派運算子,從最簡單的等號 = 到結合算術、位元或容器操作的複合指派(+=, -= …),它們不僅讓程式碼更簡潔,也能提升效能與可讀性。

了解指派運算子的行為與細節,對 初學者 來說是建立正確程式思維的第一步;對 中級開發者 而言,則是撰寫高效、易維護程式碼的關鍵技巧。本篇文章將從概念說明、實作範例、常見陷阱到最佳實踐,完整呈現 Python 指派運算子的使用方式與實務應用。


核心概念

1. 基本指派 =

最常見的指派形式是使用等號 =,將右側的表達式結果儲存到左側的變數名稱。

# 基本指派範例
x = 10          # 把整數 10 指派給變數 x
name = "Alice" # 把字串指派給變數 name
lst = [1, 2, 3] # 把列表指派給變數 lst

注意= 只負責「把值」放入變數,不會比較兩個變數是否相等(比較使用 ==)。


2. 複合指派(Compound Assignment)

複合指派結合了 算術/位元運算指派,語法為 運算子=(例如 +=-=*= …)。其背後的運作流程等價於:

a = a <operator> b

但在執行上會直接在原位(in‑place)修改變數,對可變物件(mutable)尤其有效率。

2.1 加法指派 +=

counter = 0
counter += 5   # 等同於 counter = counter + 5
print(counter) # 5
  • 字串 也支援 +=,會產生新字串:
msg = "Hello"
msg += ", World!"   # 等同於 msg = msg + ", World!"
print(msg)          # Hello, World!

2.2 減法指派 -=、乘法指派 *=、除法指派 /=、取餘指派 %=

x = 20
x -= 4   # x = x - 4   -> 16
x *= 2   # x = x * 2   -> 32
x /= 8   # x = x / 8   -> 4.0
x %= 3   # x = x % 3   -> 1.0

2.3 位元指派 &=, |=, ^=, >>=, <<=

flags = 0b1010      # 10 (十進位)
flags |= 0b0101     # 設定第 0、2 位為 1 -> 0b1111
flags ^= 0b0011     # 進行 XOR      -> 0b1100
flags <<= 2         # 左移 2 位    -> 0b110000
print(bin(flags))   # 0b110000

2.4 整除指派 //= 與指數指派 **=

y = 17
y //= 3   # y = y // 3 -> 5 (向下取整)
y **= 2   # y = y ** 2 -> 25

2.5 列表、集合與字典的原位更新

  • 列表+= 會把右側的可迭代物件展開後 原位延伸(不會產生新列表):
numbers = [1, 2, 3]
numbers += [4, 5]   # 等同於 numbers.extend([4,5])
print(numbers)      # [1, 2, 3, 4, 5]
  • 集合|=&=-= 會在原位完成集合運算:
a = {1, 2, 3}
b = {3, 4, 5}
a |= b   # a = a.union(b)  原位更新
print(a) # {1, 2, 3, 4, 5}
  • 字典|=(Python 3.9+)可以合併兩個字典:
d1 = {"x": 1, "y": 2}
d2 = {"y": 3, "z": 4}
d1 |= d2   # d1 = d1 | d2
print(d1)  # {'x': 1, 'y': 3, 'z': 4}

3. 多重指派(Multiple Assignment)

Python 允許一次指派多個變數,語法上看起來像「解構賦值」:

a, b, c = 1, 2, 3          # a=1, b=2, c=3
x = y = z = 0              # 同時把 0 指派給三個變數

此特性常用於 交換變數值,不需要暫存變數:

i, j = 5, 10
i, j = j, i   # 交換後 i=10, j=5

程式碼範例

以下示範 5 個常見且實用的指派運算子應用,附上說明與可能的錯誤情境。

範例 1:計算累積總和

total = 0
for i in range(1, 6):   # 1~5
    total += i          # 每次迭代把 i 加到 total
print("1~5 的總和:", total)   # 15

說明+= 讓累加的寫法更簡潔,避免每次都寫 total = total + i


範例 2:字串緩衝區(String Buffer)

buffer = ""
for word in ["Python", "是", "一門", "好學的", "語言"]:
    buffer += word + " "   # 逐字串拼接
print(buffer.strip())
# 輸出: Python 是 一門 好學的 語言

注意:在大量字串拼接時,+= 會產生多個暫時字串,若效能敏感,可改用 list + ''.join()


範例 3:原位更新列表

data = [10, 20, 30]
extra = [40, 50]
data += extra          # 等同於 data.extend(extra)
print(data)            # [10, 20, 30, 40, 50]

重點data 本身被改變,若有其他變數指向同一列表,它們也會同步看到變化。


範例 4:位元旗標(Flag)操作

READ   = 0b001   # 1
WRITE  = 0b010   # 2
EXEC   = 0b100   # 4

perm = 0            # 初始沒有權限
perm |= READ        # 開啟讀取權限
perm |= WRITE       # 同時開啟寫入權限
print(bin(perm))    # 0b011

# 檢查是否有執行權限
if perm & EXEC:
    print("可以執行")
else:
    print("沒有執行權限")

說明:使用 |= 把多個旗標合併成一個整數;& 用於檢查特定位元。


範例 5:字典合併(Python 3.9+)

default_cfg = {"host": "localhost", "port": 3306, "debug": False}
user_cfg    = {"port": 8080, "debug": True}

# 使用 |= 直接在 default_cfg 上更新
default_cfg |= user_cfg
print(default_cfg)
# {'host': 'localhost', 'port': 8080, 'debug': True}

最佳實踐:若需要保留原始設定,可先做 copy() 再使用 |=


常見陷阱與最佳實踐

陷阱 說明 建議的做法
可變物件的別名(alias) list_a = list_b 只會把兩個變數指向同一個列表,之後的 += 會同時改變兩者。 若需要 複製,使用 list_a = list_b.copy()list_a = list(list_b)
字串大量 += 每次 += 會產生新字串,導致 O(n²) 的時間與記憶體開銷。 改用 list 收集片段,最後 ''.join(list)
除法指派 /= 產生浮點數 在 Python 3 中,/= 永遠回傳 float,即使兩個整數相除。 若需要整數除法,使用 //=
位元指派的優先順序 a <<= 1 + 2 會先算 1 + 2 再左移。
a <<= 1 + 2a <<= (1 + 2) 同等。
使用括號明確表達意圖,避免混淆。
**字典 ` =` 的版本限制** `

最佳實踐

  1. 明確使用可變與不可變物件

    • 不可變(int、float、str、tuple)使用 += 時,其實是 重新綁定,不會改變原始物件。
    • 可變(list、dict、set)使用 +=|= 等會 原位修改,要注意別名問題。
  2. 在迴圈內盡量避免字串 +=

    • 若字串長度可能很大,改用 io.StringIOlist + join
  3. 使用複合指派提升可讀性

    • counter += 1 明顯表達「累加 1」的意圖,較 counter = counter + 1 更直觀。
  4. 善用多重指派與解構賦值

    • x, y = y, x 用於變數交換,避免臨時變數。
    • a, *b = range(5) 可快速取得「首項」與「剩餘」集合。
  5. 在函式內部避免不必要的全域變數變更

    • 若要在函式內部累計結果,考慮回傳新值或使用 nonlocal/global 明確聲明。

實際應用場景

場景 典型指派運算子 為何適合
計算機統計(例如每日銷售額累加) +=-= 累計/扣除操作頻繁,使用 +=/-= 可保持程式碼簡潔。
資料清理(把多個列表合併成一個) +=(列表) list.extend() 的語法糖,使合併更直觀。
權限管理(檔案或使用者的位元旗標) ` =, &=, ^=`
設定合併(預設設定與使用者自訂) ` =`(字典)
即時圖形或遊戲開發(位置、速度更新) +=, -=*= 物件的座標、速度常以向量形式更新,複合指派讓運算更自然。
大量文字產生(報表、HTML 模板) list.append() + ''.join()(避免 += 提升效能,避免字串大量重新分配。
演算法實作(快速排序、合併排序中的索引移動) +=, -=>>=<<= 索引的前後移動或位元操作常用於優化。

總結

指派運算子是 Python 程式設計的基石,從最簡單的 = 到功能強大的 +=|=>>= 等,掌握它們的語意與執行機制,能讓程式碼:

  • 更簡潔:減少重複寫 變數 = 變數 <op> 值 的樣板。
  • 更高效:對可變物件的原位更新避免不必要的記憶體分配。
  • 更易讀:使用直觀的符號表達「累加、減除、合併」等常見意圖。

在實務開發中,請特別留意 可變物件的別名字串大量 += 的效能問題,以及 語法支援的版本限制。遵循本文的 最佳實踐,配合適當的測試與除錯,您將能寫出既 乾淨高效 的 Python 程式。

祝您在 Python 的旅程中,玩得開心、寫得順手! 🎉