集點卡說第十杯免費,但只限十一點前,節假日還不算。一條 if 管得住第一條規則,第二條就開始疊了。縮進到底在決定哪幾行屬於同一個分支?
當程式能對不同值做出反應時,它才開始有用。條件語句只在測試為真時執行一段程式碼。Python 用縮進表示哪些行屬於同一個分支。 你還會用守衛子句替代深層巢狀,並測試邊界值。
比較運算產生布林值
== 判斷相等,!= 判斷不等,<、<=、>、>= 用於比較大小。比較的結果是 True 或 False。不要把 =(賦值)和 ==(比較)混淆。
score = 85
print(score >= 80)
print(score == 100)
print(score != 0)比較結果
只走一個分支
if 在條件為真時執行。elif 只會在前面的條件都為假時檢查。else 接收剩下的所有情況。順序很重要:通常把更嚴格或更高的門檻值放在前面。
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
else:
print("C")成績等級
組合多個條件
and 只有在兩邊都為真時才為真。or 只要至少一邊為真就為真。not 會翻轉布林值。複雜條件加上括號會更容易讀。
age = 20
member = True
print(age >= 18 and member)
print(age < 18 or member)
print(not member)布林邏輯
守衛子句讓巢狀保持扁平
當一個函式有多個前置條件時,先檢查並儘早回傳,這叫守衛子句。主路徑保持扁平,每個拒絕條件也離它產生的原因更近。
def shipping(total, member=False):
if total <= 0:
return "invalid total"
if total >= 50 or member:
return "free shipping"
return "shipping: 5.00"
for total in [0, 42, 50]:
print(total, shipping(total))
print(50, shipping(50, member=True))用提前回傳代替巢狀分支
邊界值和顯式的真假判斷
邊界值值得單獨測試。if total 會把 0 當成假,可能掩蓋無效訂單;當 0 表示缺失資料時,用 total > 0 更明確。互斥的情況放進同一條 if/elif/else 鏈。
for total in [0, 49.99, 50]:
if total <= 0:
print(total, "invalid")
elif total < 50:
print(total, "paid shipping")
else:
print(total, "free shipping")測試門檻值兩側的值
用守衛語句減少巢狀
層層巢狀會讓正常路徑很難看清。守衛語句先處理無效輸入並立刻回傳,後面的程式碼就能保持扁平。守衛語句適合處理前置條件,不適合隱藏複雜分支。讀者應該能從頂部往下掃一眼,就看到一條正常路徑。
def shipping(weight):
if weight <= 0:
return "無效"
if weight < 1:
return "小件"
return "標準"
for w in (0, 0.5, 3):
print(w, shipping(w))無效情況提前離開
本課要點
- == 比較值,= 給變數賦值。
- 條件鏈中只有第一個比對的分支會執行。
- elif 可以避免比對後繼續檢查後面的條件。
- and 要求兩邊都為真,or 只要求至少一邊為真。
- 先處理非法值,守衛子句能讓主路徑更平。
- 先處理無效輸入,正常路徑就不用縮進在條件裡面。
常見錯誤
- 把 if score = 90 寫成賦值,而不是 if score == 90 進行比較。
- 在 elif 鏈中把低門檻值放在高門檻值前面。
- 忘記冒號或縮行程式碼區塊。
- 本應互斥的條件寫成多個獨立 if。
- 把正常路徑塞進三層 if 巢狀裡。
列印運費提示:訂單滿 50 元免運費,否則顯示運費。
動手試試
改改變數、先預測輸出,再執行程式碼。第一次點擊「執行程式碼」時會下載 Python 執行時,可能需要幾秒鐘。
練習本課
12 道題,作答後立即看到解釋。