Python 課程 – 運算子(Operators)
主題:算術運算子(+ - * / // % **)
簡介
在程式語言的世界裡,算術運算子是最直觀、也是最常用的工具。無論是計算商品總價、處理統計資料,或是實作演算法,都離不開 +、-、*、/、//、%、** 這七種基本運算子。
對於剛踏入 Python 的新手而言,熟悉這些運算子的行為與細節,能夠快速寫出正確且易讀的程式;對於已有開發經驗的中階開發者,則能藉由深入了解其特性(例如除法的類型、取餘數的符號規則),避免潛在的錯誤,寫出更安全、效能更佳的程式碼。
本篇文章將逐一說明每個算術運算子的語法與運算結果,提供實用的程式碼範例,並討論常見的陷阱與最佳實踐,最後以真實的應用情境示範如何將這些運算子結合在日常開發中。
核心概念
1. 加法與減法 +、-
| 運算子 | 語意 | 範例 |
|---|---|---|
+ |
兩個數值相加,或字串、串列等可迭代物件的合併 | 3 + 5、"Hello " + "World" |
- |
兩個數值相減,或單目運算子表示負號 | 10 - 4、-a |
注意:在 Python 中,
+也可以用於串列、元組等結構的合併,前提是兩者型別相同。
程式碼範例 1:基本加減法
# 基本的加法與減法
a = 12
b = 7
sum_result = a + b # 19
diff_result = a - b # 5
print("a + b =", sum_result)
print("a - b =", diff_result)
2. 乘法 *
* 用於 數值相乘,同時也支援「序列重複」的功能,例如字串或串列乘以整數會產生重複的結果。
程式碼範例 2:乘法與序列重複
# 數值乘法
x = 4
y = 3
print("4 * 3 =", x * y) # 12
# 序列重複
s = "Python"
print(s * 3) # PythonPythonPython
lst = [1, 2]
print(lst * 4) # [1, 2, 1, 2, 1, 2, 1, 2]
3. 除法 / 與 整除 //
| 運算子 | 結果類型 | 說明 |
|---|---|---|
/ |
float | 常規除法,永遠返回浮點數,即使兩個整數相除結果是整數也會是 float。 |
// |
int 或 float | 整除(floor division),返回不大於真實商的最大整數(向下取整)。若任一操作數是 float,結果仍為 float。 |
程式碼範例 3:除法與整除的差異
a = 10
b = 3
regular_div = a / b # 3.3333333333333335 (float)
floor_div = a // b # 3 (int)
# 當其中一個是 float 時,// 仍會向下取整並回傳 float
c = 10.0
print(c // b) # 3.0
小技巧:如果你需要「捨去小數」而非「四捨五入」,使用
//是最直接的方式。
4. 餘數 %
% 取兩個數的 餘數(模),在數學上稱為「模運算」。Python 的餘數遵守 同號取餘 的規則:餘數的符號與除數(右側運算元)相同。
程式碼範例 4:模運算的正負行為
print(10 % 3) # 1 (10 = 3*3 + 1)
print(-10 % 3) # 2 (-10 = 3*(-4) + 2,餘數為正,因為除數 3 為正)
print(10 % -3) # -2 (10 = (-3)*(-4) + -2,餘數符號與除數相同)
模運算常用於 判斷奇偶、循環索引、時間週期 等情境。
5. 次方 **
** 用於 指數運算,即「底數的指數次方」。它的優先順序高於乘除法。
程式碼範例 5:次方與組合運算
# 基本次方
print(2 ** 8) # 256
# 結合其他運算子
result = (3 + 5) ** 2 / 4 # ((3+5)^2) / 4 = 64 / 4 = 16.0
print(result)
常見陷阱與最佳實踐
| 陷阱 | 說明 | 建議的最佳實踐 |
|---|---|---|
| 除法自動轉型 | 使用 / 時即使兩個都是 int,結果仍是 float,可能導致比較時出現精度問題。 |
若需要整數結果,改用 //;若必須保留小數,使用 round() 或 Decimal 進行控制。 |
| 負數模運算 | % 的結果符號與除數相同,初學者常以為餘數永遠是正數。 |
明確了解需求,必要時使用 abs() 或自行調整公式(如 (a % b + b) % b)確保正餘數。 |
| 浮點數精度 | 0.1 + 0.2 不等於 0.3,因為二進位浮點數無法精確表示某些十進位小數。 |
在財務或科學計算時,使用 decimal.Decimal 或 fractions.Fraction。 |
| 運算子優先順序 | ** 的優先順序高於 *、/,但低於單目運算子(如負號),容易產生意外結果。 |
使用括號明確表達運算順序,提升可讀性。 |
| 序列乘以負數 | list * -1 會得到空列表,這在某些情況下不易察覺。 |
在需要驗證序列長度前,先檢查乘數是否為正整數。 |
最佳實踐總結:
- 明確使用括號:即使運算子優先順序正確,也建議在複雜表達式前後加上括號,提高可讀性。
- 保持型別一致:在同一算式中盡量讓所有運算元保持相同型別(全部
int或全部float),可減少隱式轉型帶來的錯誤。 - 使用
math模組的常數:如math.pow()與**效能相近,但在需要特殊功能(如模指數)時,可直接使用pow(base, exp, mod)。
實際應用場景
1. 金融結算:計算分期付款
principal = 12000 # 總金額
months = 12 # 分 12 期
interest_rate = 0.015 # 每月利率 1.5%
# 每月應付金額 = 本金 * (1 + 月利率) ** 期數 / 期數
monthly_payment = principal * (1 + interest_rate) ** months / months
monthly_payment = round(monthly_payment, 2)
print(f"每月應付金額:${monthly_payment}")
使用 ** 計算複利,再配合除法取得均攤金額。
2. 日期輪轉:每週循環索引
weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
today_index = 4 # 假設今天是 Friday (index 4)
# 計算三天後是星期幾
future_index = (today_index + 3) % 7
print("三天後是:", weekdays[future_index]) # 輸出: Mon
此例利用 % 讓索引在 0~6 之間循環,避免陣列越界。
3. 圖形處理:像素縮放
original_width = 1920
original_height = 1080
scale_factor = 0.5 # 縮小 50%
new_width = int(original_width * scale_factor) # 使用 * 乘以比例
new_height = int(original_height * scale_factor)
print(f"新解析度: {new_width}x{new_height}")
乘法 * 搭配 int() 直接得到整數像素值,常見於 UI、遊戲開發。
4. 數據分析:分箱(binning)統計
scores = [73, 85, 91, 68, 77, 84, 90, 58]
bin_size = 10
# 計算每個分數屬於哪個區間(0-9, 10-19, ...)
bins = {}
for s in scores:
key = (s // bin_size) * bin_size # 整除取得區間下限
bins[key] = bins.get(key, 0) + 1
print(bins) # {70: 3, 80: 2, 90: 2, 50: 1}
使用 // 取得「區間底」再以字典累計,快速完成分箱統計。
總結
算術運算子是 Python 程式設計的基礎磚塊,從最簡單的 +、- 到稍微複雜的 //、%、**,每一個都有其特定的行為與適用情境。掌握它們的運算規則、型別轉換與優先順序,不僅能寫出正確的程式碼,也能避免常見的陷阱(如負數模運算、浮點精度問題)。在實務開發中,這些運算子常與 math、decimal、datetime 等模組結合,完成金融計算、時間循環、圖形縮放或資料分箱等多樣需求。
實務建議:在撰寫涉及多種算術運算的程式時,先寫測試案例,確保每一個運算子在邊界值(如負數、零、浮點數)下的行為符合預期;同時,保持程式碼的可讀性—適度使用括號與明確的變數命名,讓其他開發者(甚至未來的自己)能快速理解運算邏輯。
祝你在 Python 的學習旅程中,玩轉算術運算子,寫出更簡潔、更可靠的程式! 🚀