Day 3 運算子與邏輯運算
引言
昨天的內容中,我們學會了如何定義變數,並認識了 Python 常見的資料型別。變數是用來存放資料的容器,但僅僅把資料放進變數並不能產生實際價值,必須透過運算與比較,才能讓程式根據資料做出反應或產生新的結果。運算子是串接資料與邏輯的橋樑,也是後續條件判斷、迴圈與資料處理的基礎。
這篇文章會帶你認識 Python 的運算子家族,包括處理數值的算術運算子、判斷大小的比較運算子、組合條件的邏輯運算子,以及用簡潔方式更新的賦值運算子。最後會整理運算子的優先順序,幫助你寫出正確又可讀的運算式,避免因為順序錯誤而踩到 bug。
算術運算子
算術運算子負責數值之間的數學運算,是最直覺的一群。Python 支援加、減、乘、除四則運算,也提供整除、取餘數與次方等進階運算。整除與一般除法不同,它會把小數部分捨去,只保留整數結果;取餘數則常用於判斷倍數、環狀索引與週期性資料。
a = 10
b = 3
print(a + b) # 加法,輸出 13
print(a - b) # 減法,輸出 7
print(a * b) # 乘法,輸出 30
print(a / b) # 除法,輸出 3.3333333333333335
print(a // b) # 整除,輸出 3
print(a % b) # 取餘數,輸出 1
print(a ** b) # 次方,10 的 3 次方,輸出 1000
從輸出可以觀察到,/ 永遠回傳浮點數,即使兩個運算元都是整數也是如此;// 與 % 在運算元都是整數時會回傳整數,若任一運算元是浮點數則回傳浮點數。當你需要保留小數時用 /,需要只取整數部分時用 //。次方運算子 ** 也可以用在浮點數,例如 2 ** 0.5 會得到 2 的平方根,這在做數學運算時相當方便。
另外要注意的是,浮點數的除法因為底層是二進位表示,可能會出現像 0.1 + 0.2 不等於 0.3 的情況。如果需要精確的小數運算(例如金額),可以使用內建的 decimal 模組,或先以「分」為單位計算,最後再除以 100。
比較運算子
比較運算子用來比較兩個值,並回傳布林值 True 或 False。它們是後續條件判斷與篩選資料的基礎。Python 的比較運算子包含等於、不等於、大於、小於、大於等於、小於等於共六種。比較的內容不限於數字,字串、串列等也可以比較,規則是依序比對元素的大小。
x = 5
y = 10
print(x == y) # 等於,輸出 False
print(x != y) # 不等於,輸出 True
print(x < y) # 小於,輸出 True
print(x > y) # 大於,輸出 False
print(x <= 5) # 小於等於,輸出 True
print(y >= 10) # 大於等於,輸出 True
# 字串比較:依 Unicode 編碼逐字比對
print("apple" < "banana") # True,'a' 的編碼小於 'b'
print("Zoo" < "apple") # False,大寫 Z 排在小寫 a 之前
比較運算子在實際應用中很常見,例如判斷使用者是否成年、分數是否及格、字串是否相符、串列是否為空等。需要特別注意的是,比較 None 時建議用 is 而不是 ==,這在後續章節會再提到。另外,== 比較的是「值是否相等」,而 is 比較的是「是否為同一個物件」,兩者的意義並不相同。
邏輯運算子
邏輯運算子可以把多個比較結果組合成更複雜的條件。Python 提供 and、or、not 三個關鍵字,分別代表「而且」、「或者」、「否定」。當條件較多時,邏輯運算子能讓程式碼保持簡潔,避免把多個判斷擠在同一行。
age = 20
has_ticket = True
# and:兩個條件都成立才會回傳 True
print(age >= 18 and has_ticket) # 輸出 True
# or:只要有一個條件成立就回傳 True
is_student = False
print(is_student or age < 12) # 輸出 False
# not:把布林值反過來
print(not has_ticket) # 輸出 False
and 與 or 都有「短路求值」的特性:and 在第一個條件為 False 時,就不會再評估第二個條件;or 在第一個條件為 True 時也會提早結束。理解這個特性,可以避免不必要的運算,也能在某些情境下避免錯誤,例如避免對 None 取屬性或索引。
另一個有趣的特性是,and 與 or 並不一定回傳布林值,而是回傳「最後被評估的那個運算元」。例如 0 or "default" 會回傳 "default",因為 0 在布林情境下被視為 False,於是 or 繼續評估下一個運算元並回傳它。這個特性在設定預設值時很方便,例如 name = user_input or "匿名"。
賦值運算子
賦值運算子除了最基本的 = 之外,還有一群把運算與賦值結合的版本,例如 +=、-=、*= 等。它們可以讓程式碼更精簡,也常出現在累加、累乘、串接字串、合併串列等場景中,是寫出簡潔程式碼的好幫手。
total = 100
total += 5 # 等同 total = total + 5
print(total) # 輸出 105
total -= 20 # 等同 total = total - 20
print(total) # 輸出 85
count = 2
count *= 3 # 等同 count = count * 3
print(count) # 輸出 6
# 也能用在字串與串列
message = "Hello"
message += ", world!" # 等同 message = message + ", world!"
print(message) # 輸出 Hello, world!
nums = [1, 2, 3]
nums += [4, 5] # 等同 nums = nums + [4, 5]
print(nums) # 輸出 [1, 2, 3, 4, 5]
常見的複合賦值運算子還有 /=、//=、%=、**=,用法都是把右邊的運算結果存回原本的變數。對串列而言,+= 的效果等同於 extend(),會直接把右邊的元素附加到原串列上;如果只是想合併成一份新串列、不動到原本的物件,就要用 +。
運算子優先順序
當一個運算式中同時存在多種運算子時,Python 會依照優先順序決定誰先算。掌握優先順序能幫助你寫出正確的運算式,也能讓你判斷哪些地方需要加括號。許多初學者的 bug 其實都來自於對優先順序的誤解。
# 沒有括號時,次方最高,接著乘除,最後加減
result = 2 + 3 * 4 ** 2
print(result) # 輸出 50(先算 4**2=16,再算 3*16=48,最後 2+48)
# 用括號明確指定計算順序
result = (2 + 3) * (4 ** 2)
print(result) # 輸出 80
# 比較與邏輯運算子的順序:先比較再邏輯
score = 85
print(score >= 60 and score < 90) # True,先算出兩個比較,再做 and
大致的優先順序由高到低為:次方 **、正負號、乘除與整除與取餘數 *//////%、加減 +/-、比較運算子、邏輯 not、邏輯 and、邏輯 or。當你不確定順序時,最保險的做法就是加上括號,讓意圖一目了然,也方便日後除錯。
運算子常見誤用
初學者在使用運算子時,經常會踩到一些常見的坑。認識這些陷阱可以幫助你少走冤枉路,也能在除錯時更快定位問題。
誤用 = 與 ==:在條件判斷裡,= 是賦值,== 才是比較。例如 if x = 5: 在語法上會直接報錯;如果想比較 x 是否等於 5,必須寫成 if x == 5:。
連續比較:Python 支援像數學式一樣的連續比較,這在其他語言並不常見。
score = 75
print(60 <= score <= 100) # True,等同 60 <= score and score <= 100
整除與負數:整除 // 遇到負數時,會往「小」的方向取整。例如 -7 // 2 的結果是 -4(不是 -3),因為 -3.5 往下取整才是 -4。這在做地板除法時要特別注意。
結語
今天我們認識了 Python 的四大類運算子:算術、比較、邏輯與賦值。算術運算子負責數值運算,比較運算子負責判斷大小與相等,邏輯運算子負責組合條件,賦值運算子則讓變數的更新更精簡。熟悉這些運算子之後,就能開始寫出具有判斷與分支能力的程式。
明天,我們會把比較與邏輯運算子結合在一起,用 if、elif、else 撰寫條件判斷式,讓程式能根據不同情況執行對應的程式碼,這也是寫出有「判斷力」的程式的第一步。
留言
張貼留言