Python中條件判斷語句新手實(shí)戰(zhàn)與避坑指南
條件判斷這東西,說白了就是讓程序?qū)W會(huì)"看人下菜碟"。你輸入用戶名密碼,它判斷對不對,對了放行錯(cuò)了攔下——這就是最典型的條件控制。
我剛開始學(xué)的時(shí)候老覺得if太簡單了,有啥好講的。結(jié)果寫了個(gè)用戶注冊的邏輯,七八個(gè)if套在一起,改了一個(gè)地方崩了三個(gè)功能。后來才明白,條件判斷不在難,在怎么寫得清楚、改得動(dòng)。
這篇文章就盯著新手容易懵的點(diǎn)聊。你跟著敲一遍,至少不會(huì)再被縮進(jìn)報(bào)錯(cuò)折磨半小時(shí)。
一、布爾值與比較運(yùn)算符快速入門
條件判斷繞不開布爾值——True和False,首字母必須大寫,這個(gè)記死了。
# 哪些東西自帶布爾值?先記住這幾個(gè)
print(bool(0)) # False
print(bool(1)) # True
print(bool("")) # False
print(bool("abc")) # True
print(bool([])) # False
print(bool([1, 2])) # True
print(bool(None)) # False
空的東西大多是False,非空的基本是True。這條規(guī)則記住,后面講真假值判定的時(shí)候會(huì)用上。
比較運(yùn)算符返回的就是布爾值:
age = 20 print(age >= 18) # True print(age == 18) # False print(age != 18) # True
Python支持連寫比較,這個(gè)寫起來很舒服:
score = 85
if 80 <= score < 90:
print("良好") # 這下會(huì)打印
其他語言得寫成score >= 80 && score < 90,Python不用。
新手容易搞混的地方:=是賦值,==是判等。寫if age = 18直接報(bào)語法錯(cuò)誤,因?yàn)橘x值語句不能出現(xiàn)在條件位置。我見過有人因?yàn)檫@個(gè)卡了二十分鐘。
二、if語句基礎(chǔ)結(jié)構(gòu)與縮進(jìn)規(guī)范
先看一個(gè)完整的if結(jié)構(gòu)長啥樣:
age = int(input("輸入年齡: "))
if age >= 18:
print("你已經(jīng)成年了")
print("可以去考駕照了")
重點(diǎn)說縮進(jìn)。
Python用縮進(jìn)來表示代碼塊,不像C/Java用大括號。同一層級的代碼縮進(jìn)必須一致。
# 這樣寫會(huì)報(bào)錯(cuò)
if age >= 18:
print("成年了")
print("這行縮進(jìn)不對") # IndentationError
縮進(jìn)用幾個(gè)空格? PEP8推薦4個(gè)。但更重要的是保持統(tǒng)一,不要這段用4個(gè)空格那段用Tab。大多數(shù)編輯器可以設(shè)置"Tab轉(zhuǎn)空格",打開這個(gè)功能省很多事。
這里有個(gè)很多人不知道的:縮進(jìn)不光是空格數(shù)一致,空格和Tab混用會(huì)直接報(bào)錯(cuò),肉眼看不出來那種。VSCode右下角能看到當(dāng)前文件用的是空格還是Tab,如果混了會(huì)顯示"混合縮進(jìn)"。
# 看起來一樣,但一個(gè)用了空格一個(gè)用了Tab
if True:
print("這行用了4個(gè)空格")
print("這行用了Tab") # 肉眼看不出來,但運(yùn)行報(bào)錯(cuò)
三、elif多分支邏輯判斷實(shí)戰(zhàn)
elif是else if的縮寫,用來處理多個(gè)互斥的條件:
score = 78
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "E"
print(f"等級: {grade}") # C
注意elif的條件判斷順序是從上到下,一旦匹配就停止往下走了。score=78匹配到>=70這個(gè)分支,后面的>=60不會(huì)再判斷。
很多新手會(huì)寫出這樣的代碼:
# 畫蛇添足
if score >= 90:
grade = "A"
if score >= 80 and score < 90: # 其實(shí)不需要 and score < 90
grade = "B"
if score >= 70 and score < 80:
grade = "C"
用elif就干凈多了,而且每個(gè)條件只判斷一次。上面那種寫法不僅啰嗦,而且score=95的時(shí)候第一和第二個(gè)if都會(huì)執(zhí)行(雖然不影響結(jié)果,但浪費(fèi)性能)。
四、else默認(rèn)處理機(jī)制應(yīng)用
else是"以上條件都不滿足"時(shí)的兜底方案。很多邏輯里它充當(dāng)默認(rèn)值的角色:
# 用戶輸入用戶名,沒輸入就給個(gè)默認(rèn)名
username = input("請輸入用戶名: ")
if username.strip() == "":
username = "游客"
else:
print(f"歡迎回來, {username}")
還有錯(cuò)誤處理的場景:
import re
phone = input("輸入手機(jī)號: ")
if re.match(r'^1[3-9]\d{9}$', phone):
print("手機(jī)號格式正確")
else:
print("手機(jī)號格式有誤,請重新輸入")
else還有個(gè)容易被忽視的用法——和循環(huán)配合。for和while可以帶else,循環(huán)正常走完(沒有被break打斷)就會(huì)執(zhí)行else塊:
# 查找列表中是否有某個(gè)元素
items = [1, 2, 3, 4, 5]
target = 6
for item in items:
if item == target:
print("找到了!")
break
else:
print("沒找到") # 循環(huán)沒有被break,執(zhí)行這里
這個(gè)寫法比設(shè)一個(gè)found標(biāo)志變量清爽很多。不過新手看這個(gè)容易懵,先知道有這么回事就行。
五、嵌套條件判斷場景解析
嵌套就是if里面再套if。能避免就避免,但有些場景確實(shí)繞不開。
一個(gè)常見的嵌套場景——先判斷大條件,再細(xì)化判斷:
age = 25
has_license = True
if age >= 18:
if has_license:
print("可以租車")
else:
print("需要先考駕照")
else:
print("未成年不能租車")
這種可以優(yōu)化成and連接:
if age >= 18 and has_license:
print("可以租車")
elif age >= 18 and not has_license:
print("需要先考駕照")
else:
print("未成年不能租車")
但嵌套太深了誰也救不了:
# 三層嵌套,看五分鐘不知道在干嘛
if condition1:
if condition2:
if condition3:
do_something()
else:
do_other()
else:
do_third()
else:
do_fourth()
碰到這種代碼,要么提前返回(如果是在函數(shù)里),要么拆成多個(gè)獨(dú)立的if,要么重新設(shè)計(jì)邏輯。三層以上的嵌套基本意味著思路該理一理了。
六、and/or/not邏輯組合技巧
and:全真才真。or:一真就真。not:取反。
這部分真正的難點(diǎn)在于短路求值。
# and 短路:左邊為False,右邊根本不會(huì)執(zhí)行
def expensive_check():
print("這個(gè)函數(shù)執(zhí)行了")
return True
if False and expensive_check():
print("不會(huì)打印")
# "這個(gè)函數(shù)執(zhí)行了" 不會(huì)打印,因?yàn)樽筮叺腇alse已經(jīng)讓整個(gè)and確定為False了
# or 短路:左邊為True,右邊不執(zhí)行
if True or expensive_check():
print("會(huì)打印")
# "這個(gè)函數(shù)執(zhí)行了" 不會(huì)打印
這個(gè)特性在寫防御性代碼的時(shí)候特別有用:
# 安全地獲取嵌套字典的值
user = {"profile": {"name": "張三"}}
if user and user.get("profile") and user["profile"].get("name"):
print(user["profile"]["name"])
# 用短路特性簡化
name = user and user.get("profile") and user["profile"].get("name")
# 如果中間某個(gè)不存在,name就是False(或None),不會(huì)報(bào)錯(cuò)
再比如給默認(rèn)值:
# 如果用戶沒輸入名字,用默認(rèn)值
name = input("輸入名字: ") or "匿名用戶"
print(name)
or的短路特性讓這行代碼既安全又簡潔。但別濫用,太長的or鏈讀起來很費(fèi)勁。
七、三元表達(dá)式簡潔寫法演示
三元表達(dá)式就是把if-else壓縮成一行,語法是結(jié)果1 if 條件 else 結(jié)果2:
age = 20 status = "成年" if age >= 18 else "未成年" print(status) # 成年
這個(gè)比寫四行if-else省地方,適合簡單的二選一賦值:
# 取最大值 a, b = 10, 20 max_val = a if a > b else b # 格式化輸出 price = 99.9 tip = "需要配送費(fèi)" if price < 100 else "免配送費(fèi)"
但別把三元表達(dá)式搞復(fù)雜了:
# 讓人看不懂的寫法
result = a if a > b else b if b > c else c # 雖然能跑
# 換成if-elif-else,三秒鐘就看懂了
if a > b and a > c:
result = a
elif b > c:
result = b
else:
result = c
嵌套三元表達(dá)式基本等于給后面維護(hù)的人埋雷。我個(gè)人的標(biāo)準(zhǔn)是:寫在一行里超過80個(gè)字符,就老老實(shí)實(shí)換回if-else。
八、真假值判定規(guī)則詳解
Python里每個(gè)對象都可以當(dāng)布爾值用,不光是True和False。
會(huì)被判定為False的值(記住這幾種就夠了):
NoneFalse- 數(shù)值0(
0,0.0,0j) - 空序列/集合(
"",[],(),{},set(),range(0))
其他所有值都是True。
這個(gè)規(guī)則的妙處是你可以直接寫:
# 不用寫成 if len(name) > 0
name = "張三"
if name:
print(f"你好, {name}")
else:
print("名字不能為空")
# 不用寫成 if len(items) != 0
items = [1, 2, 3]
if items:
print(f"有{len(items)}個(gè)項(xiàng)目")
# 不用寫成 if user is not None and user != {}
user = {"name": "張三"}
if user:
print(user["name"])
很多新手會(huì)這樣寫:
if name == True: # 多此一舉 if items != []: # 雖然能跑但不Pythonic if len(name) > 0: # 可以但啰嗦
記?。?code>if x 比 if x == True 更地道,也比 if x is True 更寬松(因?yàn)楹笳咭髕必須是布爾True,而if x能接受任何真值)。
九、常見縮進(jìn)錯(cuò)誤與排查方法
條件控制相關(guān)的報(bào)錯(cuò),80%是縮進(jìn)問題。遇到這類錯(cuò)誤不用慌,挨個(gè)排查。
錯(cuò)誤1:IndentationError: expected an indented block
意思是"這里應(yīng)該有縮進(jìn)"。if、elif、else、for、while、def后面的代碼塊必須有縮進(jìn)。
# 錯(cuò)誤
if age > 18:
print("成年了") # 縮進(jìn)沒對齊
# 如果暫時(shí)不想寫邏輯,用pass占位
if age > 18:
pass # pass就是啥也不做,占位用的
錯(cuò)誤2:IndentationError: unindent does not match any outer indentation level
縮進(jìn)級別不一致。檢查前后縮進(jìn)的空格數(shù)是否相同。
錯(cuò)誤3:Tab和空格混用
編輯器里看不出來,但運(yùn)行報(bào)錯(cuò)。排查方法:
- VSCode:右下角點(diǎn)擊"空格"或"Tab"可以切換,也能看到當(dāng)前文件用的是什么
- 用
python -t運(yùn)行腳本會(huì)警告Tab和空格混用 - 編輯器設(shè)置"顯示空白字符",就能看到所有的點(diǎn)和箭頭
實(shí)踐建議:
- 編輯器設(shè)置"Tab鍵轉(zhuǎn)換為空格",并且用4個(gè)空格
- 寫代碼的時(shí)候盯著縮進(jìn)對齊線看
- 如果報(bào)縮進(jìn)錯(cuò)誤,把這段代碼的縮進(jìn)全部刪了重新打一遍
十、用戶輸入驗(yàn)證綜合案例
把上面的東西串起來,寫一個(gè)用戶注冊信息驗(yàn)證的小程序。
import re
def validate_username(username):
"""用戶名:3-12位,字母數(shù)字下劃線"""
if not username:
return False, "用戶名不能為空"
if len(username) < 3 or len(username) > 12:
return False, "用戶名長度需為3-12位"
if not re.match(r'^[a-zA-Z0-9_]+$', username):
return False, "用戶名只能包含字母、數(shù)字、下劃線"
return True, "用戶名可用"
def validate_password(password, confirm):
"""密碼:至少8位,包含字母和數(shù)字"""
if not password:
return False, "密碼不能為空"
if len(password) < 8:
return False, "密碼至少8位"
if not re.search(r'[a-zA-Z]', password):
return False, "密碼需要包含字母"
if not re.search(r'\d', password):
return False, "密碼需要包含數(shù)字"
if password != confirm:
return False, "兩次輸入的密碼不一致"
return True, "密碼可用"
def validate_email(email):
"""郵箱:簡單格式驗(yàn)證"""
if not email:
return False, "郵箱不能為空"
if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
return False, "郵箱格式不正確"
return True, "郵箱格式正確"
def main():
print("=" * 40)
print("用戶注冊信息驗(yàn)證")
print("=" * 40)
# 收集用戶輸入
username = input("用戶名: ").strip()
password = input("密碼: ").strip()
confirm = input("確認(rèn)密碼: ").strip()
email = input("郵箱: ").strip()
# 逐項(xiàng)驗(yàn)證,只要有一項(xiàng)失敗就停止
valid, msg = validate_username(username)
if not valid:
print(f"? {msg}")
return
valid, msg = validate_password(password, confirm)
if not valid:
print(f"? {msg}")
return
valid, msg = validate_email(email)
if not valid:
print(f"? {msg}")
return
# 所有驗(yàn)證通過
print("? 所有信息驗(yàn)證通過!")
print(f"用戶名: {username}")
print(f"郵箱: {email}")
print("密碼: ********")
if __name__ == "__main__":
main()
運(yùn)行效果:
========================================
用戶注冊信息驗(yàn)證
========================================
用戶名: 張三
? 用戶名只能包含字母、數(shù)字、下劃線
用戶名: zhangsan
密碼: 123456
確認(rèn)密碼: 123456
郵箱: zhangsan@qq.com
? 密碼需要包含字母
用戶名: zhangsan
密碼: abc12345
確認(rèn)密碼: abc12345
郵箱: zhangsan@qq.com
? 所有信息驗(yàn)證通過!
用戶名: zhangsan
郵箱: zhangsan@qq.com
密碼: ********
這個(gè)例子把if、elif、else、and/or/not、真假值判定、比較運(yùn)算符都串起來了。你可以試著改改驗(yàn)證規(guī)則,比如用戶名不能用純數(shù)字、密碼不能包含用戶名之類的,練練手。
最后說兩句
條件控制說到底是"讓程序做選擇題"。代碼怎么寫才算好?我自己的標(biāo)準(zhǔn)是:別人(包括三個(gè)月后的自己)看一遍就能明白這段邏輯在干嘛。
縮進(jìn)統(tǒng)一用4個(gè)空格,嵌套不超過三層,復(fù)雜的and/or鏈拆成帶名字的變量——這些小習(xí)慣比學(xué)會(huì)某個(gè)高級技巧重要得多。
前面講的驗(yàn)證案例你可以跑一遍,改改規(guī)則、換換輸入,看看輸出變化。遇到報(bào)錯(cuò)就看看是哪類縮進(jìn)錯(cuò)誤,多折騰幾次就有數(shù)了。
如果卡在某個(gè)點(diǎn)上,把這個(gè)條件拆成最簡的形式,一行一行打印中間結(jié)果,慢慢就定位到問題了。寫代碼這事兒,調(diào)試的時(shí)間永遠(yuǎn)比寫的時(shí)間長,習(xí)慣就好。
以上就是Python中條件判斷語句新手實(shí)戰(zhàn)與避坑指南的詳細(xì)內(nèi)容,更多關(guān)于Python條件判斷語句的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python playwright--pytest-playwright、pytest-base-url插件編
這篇文章主要介紹了python playwright--pytest-playwright、pytest-base-url插件編寫用例,它提供上下文隔離,開箱即用地在多個(gè)瀏覽器配置上運(yùn)行,它繼承了pytest框架,以及支持playwright的一些基礎(chǔ)使用,需要的朋友可以參考下2023-05-05
五分鐘學(xué)會(huì)怎么用Pygame做一個(gè)簡單的貪吃蛇
這篇文章主要介紹了五分鐘學(xué)會(huì)怎么用Pygame做一個(gè)簡單的貪吃蛇,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01
詳解利用python+opencv識別圖片中的圓形(霍夫變換)
這篇文章主要介紹了詳解利用python+opencv識別圖片中的圓形(霍夫變換),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Python自動(dòng)錄入ERP系統(tǒng)數(shù)據(jù)
這篇文章主要介紹了Python如何自動(dòng)錄入ERP系統(tǒng)數(shù)據(jù),用Python解決Excel問題的最佳方法,文章中有詳細(xì)的代碼示例,需要的朋友可以參考閱讀2023-04-04
python中前綴運(yùn)算符 *和 **的用法示例詳解
這篇文章主要介紹了python中前綴運(yùn)算符 *和 **的用法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-05-05

