最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解Python的流程控制if/for/while

 更新時間:2026年07月01日 09:38:11   作者:碼流怪俠  
本文詳細解析Python流程控制,涵蓋if/elif/else、for/while循環(huán)、match-case模式匹配,通過實操Demo展示猜數(shù)字游戲與簡易計算器,助你掌握條件語句、循環(huán)結(jié)構(gòu)、模式匹配等最佳實踐,需要的朋友可以參考下

本文覆蓋:條件語句(if/elif/else + 三元)、循環(huán)語句(for/while + else 子句)、range/enumerate/zip 并行迭代、break/continue/pass 循環(huán)控制、match-case 模式匹配(3.10+)、常見陷阱與最佳實踐,最后用兩個實操 Demo 收尾。

1. 介紹:為什么需要流程控制

1.1 一句話理解

流程控制 = 程序的「大腦決策系統(tǒng)」。沒有流程控制的程序就是一條直線——從第一行執(zhí)行到最后一行,中間不做任何判斷、不重復任何步驟?,F(xiàn)實中哪有這么簡單的活兒?

1.2 三大基本結(jié)構(gòu)

所有編程語言的流程控制都圍繞這三個結(jié)構(gòu)展開:

結(jié)構(gòu)作用Python 關(guān)鍵字
順序結(jié)構(gòu)代碼從上到下依次執(zhí)行(默認行為)
選擇結(jié)構(gòu)根據(jù)條件決定走哪條路if / elif / else / match-case
循環(huán)結(jié)構(gòu)重復執(zhí)行某段代碼for / while

1.3 Python 的特殊之處

跟 C/Java 比,Python 的流程控制有幾個顯著區(qū)別:

# 1. 沒有大括號 {},靠縮進劃分代碼塊
if True:
    print("縮進就是命")
    print("縮進錯了就 SyntaxError")

# 2. 循環(huán)可以帶 else 子句(是的你沒看錯,循環(huán)也有 else)
for i in range(3):
    print(i)
else:
    print("循環(huán)正常結(jié)束(沒被 break)")

# 3. 條件表達式不用括號包裹(當然加了也不報錯)
if x > 0:  # ?
if (x > 0):  # ? 但多余

2. 條件語句:if / elif / else 與三元表達式

2.1 原理:Python 的真值測試

Python 的條件判斷不是「判斷 True/False」,而是真值測試(truthiness testing)。任何對象都能被 if 測試,Python 會調(diào)用內(nèi)置的 bool() 函數(shù)來決定走哪條路。

# bool() 的底層邏輯(偽代碼)
def bool(obj):
    # 1. 先找 __bool__ 方法
    if hasattr(obj, '__bool__'):
        return obj.__bool__()
    # 2. 再找 __len__ 方法
    if hasattr(obj, '__len__'):
        return obj.__len__() > 0
    # 3. 都沒有?默認 True
    return True

假值(Falsy)清單

以下對象在 if 中等價于 False

類型假值說明
NoneTypeNone空對象
boolFalse布爾假
int0, 0整數(shù)零
float0.0浮點零
complex0j復數(shù)零
str""空字符串
list / tuple[], ()空序列
dict / set{}, set()空映射/集合
rangerange(0)空范圍
# 驗證假值
for val in [None, False, 0, 0.0, "", [], {}, set(), range(0)]:
    print(f"{repr(val):>10} -> {'假值' if not val else '真值'}")

# 輸出:
#      None -> 假值
#      False -> 假值
#         0 -> 假值
#       0.0 -> 假值
#         '' -> 假值
#        [] -> 假值
#        {} -> 假值
#      set() -> 假值
#   range(0, 0) -> 假值

踩坑點: 0.0 是假值,但 0.0000001 不是。別用浮點數(shù)做條件判斷,精度問題會咬人。

2.2 if / elif / else 完整語法

# 完整結(jié)構(gòu)
if condition_1:
    # 條件1為真時執(zhí)行
    pass
elif condition_2:
    # 條件1為假、條件2為真時執(zhí)行
    pass
elif condition_3:
    # 前面都假、條件3為真時執(zhí)行
    pass
else:
    # 以上條件全假時執(zhí)行(可選)
    pass

執(zhí)行流程

condition_1 ──True──? 執(zhí)行代碼塊1 ──? 跳出整個if
     │
   False
     ▼
condition_2 ──True──? 執(zhí)行代碼塊2 ──? 跳出整個if
     │
   False
     ▼
condition_3 ──True──? 執(zhí)行代碼塊3 ──? 跳出整個if
     │
   False
     ▼
  else(可選)──? 執(zhí)行else代碼塊

實際示例:成績等級判定

def grade_level(score: float) -> str:
    """根據(jù)分數(shù)返回等級"""
    if score >= 90:
        return "A - 優(yōu)秀"
    elif score >= 80:
        return "B - 良好"
    elif score >= 70:
        return "C - 中等"
    elif score >= 60:
        return "D - 及格"
    else:
        return "F - 不及格"

# 測試
for score in [95, 85, 75, 65, 55]:
    print(f"{score}分 -> {grade_level(score)}")

# 輸出:
# 95分 -> A - 優(yōu)秀
# 85分 -> B - 良好
# 75分 -> C - 中等
# 65分 -> D - 及格
# 55分 -> F - 不及格

C++ 對比: Python 沒有 switch 語句(3.10 前沒有,3.10 后用 match-case 替代)。多個 elif 就是 Python 式的 switch。在 C++ 里你可以 switch(score / 10),Python 里通常用 elif 鏈或者查表法(bisect 模塊)。

2.3 三元表達式(條件表達式)

當 if-else 只有一個表達式時,Python 提供了簡潔的三元寫法:

# 語法:value_if_true if condition else value_if_false
result = "成年" if age >= 18 else "未成年"

# 等價于
if age >= 18:
    result = "成年"
else:
    result = "未成年"

嵌套三元(謹慎使用)

# 三層嵌套三元 —— 能用但別濫用
status = "優(yōu)秀" if score >= 90 else ("及格" if score >= 60 else "不及格")

# 更推薦拆開寫
if score >= 90:
    status = "優(yōu)秀"
elif score >= 60:
    status = "及格"
else:
    status = "不及格"

踩坑點: 三元表達式的求值順序是先判斷條件,再求值對應分支,不是兩個分支都求值。

# 安全:只有條件為真時才調(diào)用 expensive_func()
result = cheap_value if condition else expensive_func()

2.4 條件組合:and / or / not

# and:兩邊都真才真(短路:左邊假就不看右邊了)
if age >= 18 and has_id:
    print("可以進入")

# or:一邊真就真(短路:左邊真就不看右邊了)
if is_vip or is_admin:
    print("有特權(quán)")

# not:取反
if not is_banned:
    print("賬號正常")

短路求值的妙用

# 模式1:默認值賦值(Python 3.8+ 用海象運算符更優(yōu)雅)
name = user_input or "匿名"

# 模式2:安全調(diào)用(避免 None 上的屬性訪問)
# 如果 obj 不為 None,才調(diào)用 obj.method()
obj is not None and obj.method()

# 模式3:鏈式比較(Python 獨有,C++ 不行)
if 0 <= score <= 100:
    print("合法分數(shù)")

# 等價于
if 0 <= score and score <= 100:
    print("合法分數(shù)")

C++ 對比: C++ 里 0 <= score <= 100 會被解析成 (0 <= score) <= 100,即先算 0 <= score 得到 true/false(1/0),再拿這個值跟 100 比——永遠為真!Python 的鏈式比較是語法糖,會正確展開成 0 <= score and score <= 100。

3. 循環(huán)語句:for / while 與 else 子句

3.1 for 循環(huán):遍歷的藝術(shù)

Python 的 for 不是 C 的 for(i=0; i<n; i++),它是基于迭代器協(xié)議的——每次從可迭代對象里取一個元素,直到取完。

# 基本語法
for element in iterable:
    # 對每個 element 執(zhí)行
    pass

# 遍歷列表
fruits = ["蘋果", "香蕉", "橙子"]
for fruit in fruits:
    print(fruit)

# 遍歷字符串
for char in "Hello":
    print(char, end=" ")  # H e l l o

# 遍歷字典
person = {"name": "yance", "age": 30, "role": "blogger"}
for key in person:            # 默認遍歷 key
    print(key, person[key])
for key, value in person.items():  # 同時取 key 和 value
    print(f"{key}: {value}")

迭代器協(xié)議底層原理

# for 循環(huán)的等價偽代碼
iterator = iter(iterable)        # 調(diào)用 iterable.__iter__()
while True:
    try:
        element = next(iterator)  # 調(diào)用 iterator.__next__()
        # 執(zhí)行循環(huán)體
        ...
    except StopIteration:         # 迭代器耗盡
        break
# 手動模擬 for 循環(huán)
my_list = [10, 20, 30]
it = iter(my_list)
print(type(it))        # <class 'list_iterator'>
print(next(it))        # 10
print(next(it))        # 20
print(next(it))        # 30
# print(next(it))      # StopIteration!

3.2 while 循環(huán):條件驅(qū)動

# 基本語法
while condition:
    # condition 為真時反復執(zhí)行
    pass

# 倒計時
count = 5
while count > 0:
    print(f"倒計時:{count}")
    count -= 1
print("發(fā)射!??")

# 輸出:
# 倒計時:5
# 倒計時:4
# 倒計時:3
# 倒計時:2
# 倒計時:1
# 發(fā)射!??

while True + break 模式

# 經(jīng)典模式:無限循環(huán) + 條件退出
while True:
    user_input = input("輸入 quit 退出:")
    if user_input == "quit":
        break
    print(f"你輸入了:{user_input}")

踩坑點: while 循環(huán)最容易犯的錯就是忘記更新條件變量,導致死循環(huán)。

# ? 死循環(huán)!count 永遠是 5
count = 5
while count > 0:
    print(count)
    # 忘了 count -= 1

# ? 正確
count = 5
while count > 0:
    print(count)
    count -= 1

3.3 循環(huán)的 else 子句(Python 獨有特性)

這是 Python 最反直覺的特性之一——循環(huán)也有 else

語義

  • for...else:循環(huán)正常結(jié)束(沒被 break 打斷)時,執(zhí)行 else
  • while...else:條件變假導致循環(huán)結(jié)束時(沒被 break 打斷),執(zhí)行 else
# for...else:查找質(zhì)數(shù)
for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(f"{n} = {x} * {n // x}")
            break
    else:
        # 如果內(nèi)層 for 沒被 break(即沒找到因子),說明 n 是質(zhì)數(shù)
        print(f"{n} 是質(zhì)數(shù)")

# 輸出:
# 2 是質(zhì)數(shù)
# 3 是質(zhì)數(shù)
# 4 = 2 * 2
# 5 是質(zhì)數(shù)
# 6 = 2 * 3
# 7 是質(zhì)數(shù)
# 8 = 2 * 4
# 9 = 3 * 3

理解 else 的觸發(fā)條件

# 情況1:正常結(jié)束 -> else 執(zhí)行
for i in range(3):
    print(i)
else:
    print("else 執(zhí)行了")  # ? 會執(zhí)行

# 情況2:被 break -> else 不執(zhí)行
for i in range(3):
    print(i)
    if i == 1:
        break
else:
    print("else 執(zhí)行了")  # ? 不會執(zhí)行
循環(huán)執(zhí)行流程:

for/while ──? 循環(huán)體
                │
        ┌───────┴───────┐
        │               │
    遇到 break      正常結(jié)束
        │               │
        ▼               ▼
    跳出循環(huán)        執(zhí)行 else 塊
    (跳過 else)    然后繼續(xù)后續(xù)代碼

踩坑點: 很多人把 for...else 理解成「循環(huán)沒執(zhí)行時才走 else」,這是錯的??昭h(huán)也會走 else:

for i in range(0):  # 循環(huán)體一次都不執(zhí)行
    pass
else:
    print("else 照樣執(zhí)行")  # ? 會執(zhí)行,因為沒有 break

最佳實踐: 如果你覺得 for...else 難讀,用標志變量替代完全沒問題:

found = False
for x in range(2, n):
    if n % x == 0:
        found = True
        break
if not found:
    print(f"{n} 是質(zhì)數(shù)")

4. range / enumerate / zip 并行迭代

4.1 range:生成整數(shù)序列

range 是 Python 中最常用的迭代工具之一,它不實際生成列表,而是一個惰性序列對象。

# 三種形式
range(stop)            # 0, 1, 2, ..., stop-1
range(start, stop)     # start, start+1, ..., stop-1
range(start, stop, step)  # start, start+step, start+2*step, ...

# 基本用法
for i in range(5):
    print(i, end=" ")      # 0 1 2 3 4

for i in range(2, 6):
    print(i, end=" ")      # 2 3 4 5

for i in range(0, 10, 2):
    print(i, end=" ")      # 0 2 4 6 8

# 倒序
for i in range(10, 0, -1):
    print(i, end=" ")      # 10 9 8 7 6 5 4 3 2 1

range 的惰性特性

r = range(1000000)  # 不會占內(nèi)存!
print(type(r))       # <class 'range'>
print(len(r))        # 1000000
print(r[0])          # 0    —— 支持索引
print(r[-1])         # 999999
print(500 in r)      # True  —— 支持成員測試

# range 對象只存儲 start, stop, step 三個值
# 不管范圍多大,內(nèi)存占用恒定
import sys
print(sys.getsizeof(range(10)))       # 48 字節(jié)
print(sys.getsizeof(range(1000000)))  # 48 字節(jié) —— 一樣大!

踩坑點: range 對象不支持 + 拼接和 * 重復,這些是 list 的操作。

# ? TypeError
range(3) + range(3)

# ? 轉(zhuǎn)成 list 或用 itertools.chain
list(range(3)) + list(range(3))  # [0, 1, 2, 0, 1, 2]

4.2 enumerate:帶索引遍歷

當你需要「同時拿索引和元素」時,enumerate 是 Pythonic 的做法。

# ? 不推薦:手動維護索引
i = 0
for fruit in fruits:
    print(i, fruit)
    i += 1

# ? 不推薦:用 range(len())
for i in range(len(fruits)):
    print(i, fruits[i])

# ? 推薦:enumerate
for index, fruit in enumerate(fruits):
    print(index, fruit)

# enumerate 還能指定起始索引
for index, fruit in enumerate(fruits, start=1):
    print(f"第{index}個:{fruit}")

enumerate 底層實現(xiàn)

# enumerate 的等價實現(xiàn)
def my_enumerate(iterable, start=0):
    n = start
    for elem in iterable:
        yield n, elem
        n += 1

# 它返回的是 enumerate 對象,不是列表
e = enumerate(["a", "b", "c"])
print(type(e))  # <class 'enumerate'>
print(list(e))  # [(0, 'a'), (1, 'b'), (2, 'c')]

4.3 zip:并行迭代多個序列

zip 把多個可迭代對象「拉鏈式」合并,每次取各序列的一個元素組成元組。

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["北京", "上海", "深圳"]

# 基本用法:兩兩配對
for name, age in zip(names, ages):
    print(f"{name} 今年 {age} 歲")

# 多個序列并行
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}歲, 住在{city}")

# 輸出:
# Alice, 25歲, 住在北京
# Bob, 30歲, 住在上海
# Charlie, 35歲, 住在深圳

zip 的「木桶效應」

# zip 以最短的那個序列為準
a = [1, 2, 3, 4, 5]
b = ["a", "b", "c"]
print(list(zip(a, b)))  # [(1, 'a'), (2, 'b'), (3, 'c')]  —— 4和5丟了!

# 如果要保留所有元素,用 itertools.zip_longest
from itertools import zip_longest
print(list(zip_longest(a, b, fillvalue="?")))
# [(1, 'a'), (2, 'b'), (3, 'c'), (4, '?'), (5, '?')]

zip 的妙用:矩陣轉(zhuǎn)置

# 經(jīng)典技巧:二維矩陣轉(zhuǎn)置
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

transposed = list(zip(*matrix))
print(transposed)  # [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

# *matrix 展開 = zip([1,2,3], [4,5,6], [7,8,9])
# zip 從每個子列表取第1個元素組成第1個元組,以此類推

zip 創(chuàng)建字典

keys = ["name", "age", "city"]
values = ["yance", 30, "深圳"]

# Pythonic 的字典構(gòu)造法
person = dict(zip(keys, values))
print(person)  # {'name': 'yance', 'age': 30, 'city': '深圳'}

Python 3 的坑: Python 3 的 zip 返回的是迭代器(惰性的),只能遍歷一次。Python 2 返回的是列表。

z = zip([1, 2], ["a", "b"])
print(list(z))  # [(1, 'a'), (2, 'b')]
print(list(z))  # [] —— 迭代器已經(jīng)耗盡了!

5. break / continue / pass 與循環(huán)控制

5.1 三者對比

關(guān)鍵字作用影響范圍
break跳出當前循環(huán)(徹底結(jié)束循環(huán))最近的 for / while
continue跳過本次迭代剩余代碼,進入下一次最近的 for / while
pass什么都不做(占位符)無影響

5.2 break:跳出循環(huán)

# 找到第一個能被7整除的數(shù)
for n in range(1, 100):
    if n % 7 == 0:
        print(f"找到了:{n}")
        break  # 找到就停,不繼續(xù)了

# 輸出:找到了:7

break 只跳一層

# 嵌套循環(huán)中,break 只跳出最內(nèi)層
for i in range(3):
    for j in range(3):
        if j == 1:
            break  # 只跳出內(nèi)層 for
        print(f"i={i}, j={j}")

# 輸出:
# i=0, j=0
# i=1, j=0
# i=2, j=0

跳出多層循環(huán)的技巧

# 方法1:標志變量
found = False
for i in range(5):
    for j in range(5):
        if i * j == 6:
            found = True
            break  # 跳出內(nèi)層
    if found:
        break  # 跳出外層

# 方法2:for...else + break(更 Pythonic)
for i in range(5):
    for j in range(5):
        if i * j == 6:
            print(f"找到:i={i}, j={j}")
            break
    else:
        continue  # 內(nèi)層沒 break,繼續(xù)外層
    break  # 內(nèi)層 break 了,也跳出外層

# 方法3:封裝成函數(shù) + return(最推薦)
def find_pair():
    for i in range(5):
        for j in range(5):
            if i * j == 6:
                return i, j
    return None

result = find_pair()

5.3 continue:跳過本次

# 打印所有奇數(shù)
for n in range(1, 10):
    if n % 2 == 0:
        continue  # 偶數(shù)跳過,不執(zhí)行后面的 print
    print(n, end=" ")  # 1 3 5 7 9

# 過濾列表中的空字符串
data = ["hello", "", "world", None, "python", ""]
for item in data:
    if not item:  # 空字符串和 None 都是假值
        continue
    print(item)

# 輸出:
# hello
# world
# python

踩坑點: continuewhile 循環(huán)中要特別小心——確保它在條件變量更新之前不會跳過更新。

# ? 死循環(huán)!continue 跳過了 count += 1
count = 0
while count < 5:
    if count == 2:
        continue  # count 永遠停在 2...
    print(count)
    count += 1

# ? 正確:把更新放在 continue 之前
count = 0
while count < 5:
    if count != 2:
        print(count)
    count += 1  # 更新一定執(zhí)行

5.4 pass:占位符

pass 是一個空操作——什么都不做。它存在的唯一意義是語法占位,因為 Python 的代碼塊不能為空。

# 1. 空函數(shù)/類的占位
def not_implemented_yet():
    pass  # 先占個位,以后再寫

class EmptyClass:
    pass

# 2. 條件分支的占位
if debug_mode:
    pass  # TODO: 加調(diào)試邏輯
else:
    do_something()

# 3. 在 try-except 中忽略異常
try:
    risky_operation()
except SomeError:
    pass  # 故意忽略這個異常

pass vs … (Ellipsis)

# Python 3 中,... 也能做占位符
def stub():
    ...

class Empty:
    ...

# ... 和 pass 效果一樣,但 ... 是一個真正的對象(Ellipsis)
# pass 是語句,... 是表達式
# 類型標注中 ... 有特殊含義
def callback() -> ...:
    ...

最佳實踐: except: pass 是 Python 中最被詬病的模式之一(被稱為「吞掉異?!梗?。如果你真的要忽略異常,至少記錄一下日志:

# ? 吞異常,出了問題無從排查
try:
    do_something()
except Exception:
    pass

# ? 至少記錄一下
import logging
try:
    do_something()
except Exception as e:
    logging.warning(f"操作失敗: {e}")

6. match-case 模式匹配(Python 3.10+)

6.1 介紹

Python 3.10 引入了 match-case,這不是簡單的 switch-case,而是結(jié)構(gòu)化模式匹配(Structural Pattern Matching)——源自函數(shù)式語言(如 Haskell、Scala、Rust)的強大特性。

# 基本語法
match subject:
    case pattern_1:
        # 匹配 pattern_1 時執(zhí)行
        pass
    case pattern_2:
        # 匹配 pattern_2 時執(zhí)行
        pass
    case _:
        # 都不匹配時執(zhí)行(_ 是通配符)
        pass

6.2 各種模式

字面量模式

def http_status(code: int) -> str:
    match code:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Internal Server Error"
        case _:
            return "Unknown"

print(http_status(200))  # OK
print(http_status(404))  # Not Found

變量綁定模式

# 匹配的值會綁定到變量上
point = (3, 4)

match point:
    case (0, 0):
        print("原點")
    case (0, y):
        print(f"在Y軸上,y={y}")  # y 綁定為 4
    case (x, 0):
        print(f"在X軸上,x={x}")
    case (x, y):
        print(f"坐標:({x}, {y})")  # x=3, y=4

類模式

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def describe(point: Point) -> str:
    match point:
        case Point(x=0, y=0):
            return "原點"
        case Point(x=0, y=y):
            return f"Y軸上,y={y}"
        case Point(x=x, y=0):
            return f"X軸上,x={x}"
        case Point(x=x, y=y):
            return f"普通點({x}, {y})"

print(describe(Point(3, 4)))  # 普通點(3, 4)

序列模式

def process_command(cmd: list) -> str:
    match cmd:
        case ["quit"]:
            return "退出程序"
        case ["help"]:
            return "顯示幫助"
        case ["go", direction]:
            return f"向{direction}移動"
        case ["go", direction, distance]:
            return f"向{direction}移動{distance}步"
        case ["look", *rest]:
            return f"查看:{rest}"  # *rest 捕獲剩余元素
        case _:
            return "未知命令"

print(process_command(["go", "north"]))       # 向north移動
print(process_command(["go", "north", 5]))     # 向north移動5步
print(process_command(["look", "around"]))     # 查看:['around']

映射(字典)模式

def handle_event(event: dict) -> str:
    match event:
        case {"type": "click", "x": x, "y": y}:
            return f"點擊坐標({x}, {y})"
        case {"type": "keypress", "key": key}:
            return f"按鍵:{key}"
        case {"type": "scroll", "delta": delta}:
            return f"滾動:{delta}"
        case _:
            return "未知事件"

print(handle_event({"type": "click", "x": 100, "y": 200}))
# 點擊坐標(100, 200)

守衛(wèi)(Guard)模式

def classify_number(n: int) -> str:
    match n:
        case n if n < 0:
            return "負數(shù)"
        case n if n == 0:
            return "零"
        case n if n < 10:
            return "小正數(shù)"
        case n if n < 100:
            return "中等正數(shù)"
        case _:
            return "大正數(shù)"

print(classify_number(-5))   # 負數(shù)
print(classify_number(0))    # 零
print(classify_number(7))    # 小正數(shù)
print(classify_number(50))   # 中等正數(shù)
print(classify_number(999))  # 大正數(shù)

or 模式

def day_type(day: str) -> str:
    match day.lower():
        case "saturday" | "sunday":
            return "周末"
        case "monday" | "tuesday" | "wednesday" | "thursday" | "friday":
            return "工作日"
        case _:
            return "無效輸入"

6.3 match-case vs if-elif-else 對比

# 傳統(tǒng) if-elif 寫法
def handle_http(method, path):
    if method == "GET" and path == "/users":
        return "獲取用戶列表"
    elif method == "GET" and path.startswith("/users/"):
        user_id = path.split("/")[-1]
        return f"獲取用戶{user_id}"
    elif method == "POST" and path == "/users":
        return "創(chuàng)建用戶"
    else:
        return "未知路由"

# match-case 寫法(更清晰)
def handle_http_v2(method, path):
    parts = path.strip("/").split("/")
    match (method, parts):
        case ("GET", ["users"]):
            return "獲取用戶列表"
        case ("GET", ["users", user_id]):
            return f"獲取用戶{user_id}"
        case ("POST", ["users"]):
            return "創(chuàng)建用戶"
        case _:
            return "未知路由"

踩坑點: match-case 中的變量名如果和已有變量重名,會被當作新的綁定模式,而不是值比較!

status = 200

# ? 這不是比較 status == 200
match response:
    case status:  # 這是變量綁定!永遠匹配
        print(f"綁定了: {status}")  # status 被重新賦值為 response 的值

# ? 要做值比較,用字面量或加了點號的變量
match response:
    case 200:
        print("OK")
    case _:  # 通配符
        print("其他")

7. 常見陷阱與最佳實踐

7.1 陷阱清單

陷阱1:在循環(huán)中修改正在遍歷的列表

# ? 邊遍歷邊刪除,會跳過元素
nums = [1, 2, 2, 3, 4, 4, 5]
for n in nums:
    if n % 2 == 0:
        nums.remove(n)
print(nums)  # [1, 2, 3, 4, 5]  —— 沒刪干凈!

# ? 方法1:遍歷副本
for n in nums[:]:  # nums[:] 創(chuàng)建副本
    if n % 2 == 0:
        nums.remove(n)

# ? 方法2:列表推導式(更 Pythonic)
nums = [n for n in nums if n % 2 != 0]

# ? 方法3:filter
nums = list(filter(lambda n: n % 2 != 0, nums))

陷阱2:可變默認參數(shù)與循環(huán)

# ? 默認參數(shù)在函數(shù)定義時只創(chuàng)建一次
def add_item(item, lst=[]):  # lst 在多次調(diào)用間共享!
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2]  —— 不是 [2]!

# ? 用 None 做默認值
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

陷阱3:浮點數(shù)做循環(huán)條件

# ? 浮點精度問題可能導致意外行為
i = 0.0
while i != 1.0:  # 可能永遠不等!
    i += 0.1
    print(i)
    if i > 2:  # 加個安全閥
        break

# ? 用整數(shù)范圍 + 縮放
for i in range(11):
    val = i / 10.0
    print(val)

陷阱4:無限循環(huán)耗盡資源

# ? 忘記更新條件
while True:
    response = fetch_data()
    if response is None:
        break
    process(response)
    # 如果 fetch_data 永遠不返回 None...死循環(huán)

# ? 加超時/最大重試限制
max_retries = 100
retry_count = 0
while retry_count < max_retries:
    response = fetch_data()
    if response is None:
        break
    process(response)
    retry_count += 1

7.2 最佳實踐

實踐1:用列表推導式替代簡單循環(huán)

# ? 傳統(tǒng)寫法
squares = []
for i in range(10):
    squares.append(i ** 2)

# ? 列表推導式
squares = [i ** 2 for i in range(10)]

# 帶條件過濾
even_squares = [i ** 2 for i in range(10) if i % 2 == 0]

實踐2:用 any() / all() 替代顯式循環(huán)

# ? 顯式循環(huán)找滿足條件的元素
def has_negative(nums):
    for n in nums:
        if n < 0:
            return True
    return False

# ? any() 一行搞定
def has_negative(nums):
    return any(n < 0 for n in nums)

# all():所有元素都滿足條件
all_positive = all(n > 0 for n in nums)

實踐3:循環(huán)中避免重復計算

# ? 每次循環(huán)都調(diào)用 len()
for i in range(len(data)):
    process(data[i], len(data))  # len(data) 每次都算

# ? 緩存長度
n = len(data)
for i in range(n):
    process(data[i], n)

實踐4:用字典替代冗長的 if-elif 鏈

# ? 冗長的 if-elif
def calculate(a, b, op):
    if op == "+":
        return a + b
    elif op == "-":
        return a - b
    elif op == "*":
        return a * b
    elif op == "/":
        return a / b
    else:
        raise ValueError(f"未知運算符: {op}")

# ? 字典分發(fā)(策略模式)
import operator
ops = {
    "+": operator.add,
    "-": operator.sub,
    "*": operator.mul,
    "/": operator.truediv,
}

def calculate(a, b, op):
    if op not in ops:
        raise ValueError(f"未知運算符: {op}")
    return ops[op](a, b)

8. 實操 Demo

8.1 猜數(shù)字游戲

"""
猜數(shù)字游戲
- 電腦隨機生成 1-100 的數(shù)字
- 玩家輸入猜測,電腦提示「大了」或「小了」
- 限制最多 7 次機會(二分法理論最優(yōu))
- 支持「放棄」提前退出
"""
import random


def guess_number_game() -> None:
    target = random.randint(1, 100)
    max_attempts = 7
    print("=" * 40)
    print("?? 猜數(shù)字游戲(1-100)")
    print(f"你有 {max_attempts} 次機會,輸入 'quit' 放棄")
    print("=" * 40)

    for attempt in range(1, max_attempts + 1):
        user_input = input(f"第 {attempt}/{max_attempts} 次猜測:").strip()

        # 處理退出
        if user_input.lower() in ("quit", "exit", "q"):
            print(f"你放棄了!答案是 {target}")
            return

        # 處理非數(shù)字輸入
        if not user_input.isdigit():
            print("?? 請輸入數(shù)字!")
            continue  # 不消耗次數(shù)(視規(guī)則而定)

        guess = int(user_input)

        # 范圍檢查
        if not (1 <= guess <= 100):
            print("?? 請輸入 1-100 之間的數(shù)字!")
            continue

        # 比較
        if guess == target:
            print(f"?? 恭喜!{attempt} 次猜中!")
            return
        elif guess < target:
            print("?? 小了!")
        else:
            print("?? 大了!")

    # 循環(huán)正常結(jié)束(次數(shù)用完沒猜中)
    else:
        print(f"?? 機會用完!答案是 {target}")


# 運行游戲
if __name__ == "__main__":
    guess_number_game()

運行效果:

========================================
?? 猜數(shù)字游戲(1-100)
你有 7 次機會,輸入 'quit' 放棄
========================================
第 1/7 次猜測:50
?? 小了!
第 2/7 次猜測:75
?? 大了!
第 3/7 次猜測:62
?? 小了!
第 4/7 次猜測:68
?? 大了!
第 5/7 次猜測:65
?? 恭喜!5 次猜中!

8.2 簡易計算器

"""
簡易計算器
- 支持加減乘除、取余、冪運算
- 支持連續(xù)計算
- 輸入 'quit' 退出
- 完整的錯誤處理
"""
import operator
import sys


# 運算符映射表
OPERATIONS = {
    "+": (operator.add, "加法"),
    "-": (operator.sub, "減法"),
    "*": (operator.mul, "乘法"),
    "/": (operator.truediv, "除法"),
    "http://": (operator.floordiv, "整除"),
    "%": (operator.mod, "取余"),
    "**": (operator.pow, "冪運算"),
}


def get_number(prompt: str) -> float | None:
    """安全地獲取數(shù)字輸入,返回 None 表示退出"""
    while True:
        raw = input(prompt).strip()
        if raw.lower() in ("quit", "exit", "q"):
            return None
        try:
            return float(raw)
        except ValueError:
            print("?? 輸入無效,請重新輸入數(shù)字!")


def get_operator() -> str | None:
    """獲取運算符輸入"""
    ops_display = " / ".join(OPERATIONS.keys())
    while True:
        raw = input(f"選擇運算符 ({ops_display}):").strip()
        if raw.lower() in ("quit", "exit", "q"):
            return None
        if raw in OPERATIONS:
            return raw
        print("?? 無效運算符,請重新輸入!")


def calculate(a: float, op: str, b: float) -> float:
    """執(zhí)行計算"""
    func, _ = OPERATIONS[op]
    return func(a, b)


def calculator() -> None:
    print("=" * 50)
    print("?? 簡易計算器")
    print("輸入 'quit' 隨時退出")
    print("=" * 50)

    while True:
        # 獲取第一個操作數(shù)
        a = get_number("請輸入第一個數(shù):")
        if a is None:
            break

        # 獲取運算符
        op = get_operator()
        if op is None:
            break

        # 獲取第二個操作數(shù)
        b = get_number("請輸入第二個數(shù):")
        if b is None:
            break

        # 執(zhí)行計算(帶異常處理)
        try:
            result = calculate(a, op, b)
            op_name = OPERATIONS[op][1]
            print(f"\n? 結(jié)果:{a} {op}  = {result}\n")

            # 特殊情況提示
            if op == "/" and b == 0:
                print("(除以零會產(chǎn)生 inf)")
            elif op == "http://" and b == 0:
                print("(整除零會拋異常,已被捕獲)")

        except ZeroDivisionError:
            print("\n? 錯誤:除數(shù)不能為零!\n")
        except OverflowError:
            print("\n? 錯誤:結(jié)果溢出!\n")
        except Exception as e:
            print(f"\n? 未知錯誤:{e}\n")

    print("感謝使用,再見!??")


# 運行計算器
if __name__ == "__main__":
    calculator()

運行效果:

==================================================
?? 簡易計算器
輸入 'quit' 隨時退出
==================================================
請輸入第一個數(shù):10
選擇運算符 (+ / - / * / / / // / % / **):**
請輸入第二個數(shù):3

? 結(jié)果:10.0 ** 3.0 = 1000.0

請輸入第一個數(shù):100
選擇運算符 (+ / - / * / / / // / % / **):/
請輸入第二個數(shù):0

? 錯誤:除數(shù)不能為零!

請輸入第一個數(shù):quit
感謝使用,再見!??

9. 總結(jié)

9.1 知識圖譜

流程控制
├── 條件分支
│   ├── if / elif / else          # 基本條件判斷
│   ├── 三元表達式                  # value if cond else value
│   ├── and / or / not            # 邏輯組合 + 短路求值
│   └── match-case (3.10+)        # 結(jié)構(gòu)化模式匹配
├── 循環(huán)
│   ├── for                       # 遍歷可迭代對象
│   ├── while                     # 條件驅(qū)動循環(huán)
│   └── else 子句                  # 循環(huán)正常結(jié)束時執(zhí)行
├── 迭代工具
│   ├── range                     # 惰性整數(shù)序列
│   ├── enumerate                 # 帶索引遍歷
│   └── zip                       # 并行迭代
├── 循環(huán)控制
│   ├── break                     # 跳出循環(huán)
│   ├── continue                  # 跳過本次
│   └── pass                      # 空操作占位
└── 最佳實踐
    ├── 列表推導式替代簡單循環(huán)
    ├── any() / all() 替代顯式查找
    ├── 字典分發(fā)替代 if-elif 鏈
    └── 避免在循環(huán)中修改遍歷對象

9.2 速查表

場景推薦示例
簡單二選一三元表達式x if cond else y
多分支if-elif-else成績等級判定
遍歷序列forfor item in list
不知道次數(shù)while讀取直到 EOF
帶索引遍歷enumeratefor i, v in enumerate(lst)
多序列并行zipfor a, b in zip(l1, l2)
復雜結(jié)構(gòu)匹配match-case解析命令/事件
查找元素any()any(x > 0 for x in lst)
過濾+變換列表推導式[f(x) for x in lst if cond]

9.3 C++ 程序員的 Python 流程控制速記

C++Python備注
if (x) {}if x:不用括號,靠縮進
switch-casematch-case (3.10+) 或 elif3.10 前沒有 switch
for (int i=0; i<n; i++)for i in range(n):基于迭代器
for (auto& x : container)for x in container:天然支持
while (x)while x:一樣
break / continuebreak / continue一樣
{} 空代碼塊passPython 代碼塊不能為空
#define MAX 100MAX = 100不用預處理器
goto? 不存在用函數(shù) + return 替代

以上就是一文詳解Python的流程控制if/for/while的詳細內(nèi)容,更多關(guān)于Python流程控制if/for/while的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • django 2.0更新的10條注意事項總結(jié)

    django 2.0更新的10條注意事項總結(jié)

    Django 是 Python Web 開發(fā)最常用的框架之一,跟進它的最新變化絕對是必須的。下面這篇文章主要給大家介紹了關(guān)于django 2.0更新的10條注意事項,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2018-01-01
  • python?中的?super詳解

    python?中的?super詳解

    這篇文章主要介紹了python?中的?super,提到 super,最直接的想法就是它代表了父類,替父類執(zhí)行某些方法,但是理解也僅止步于此,下面對 super 做進一步理解,需要的朋友可以參考下
    2022-08-08
  • Python接口自動化之淺析requests模塊post請求

    Python接口自動化之淺析requests模塊post請求

    這篇文章Python接口自動化之淺析requests模塊post請求,以下主要介紹requests模塊中的post請求的使用,post源碼,data、json參數(shù)應用場景及實戰(zhàn)
    2021-08-08
  • VSCode設置類似Pycharm控制臺運行Python顯示中間變量的步驟

    VSCode設置類似Pycharm控制臺運行Python顯示中間變量的步驟

    這篇文章主要介紹了如何在VSCode中設置調(diào)試功能,以實現(xiàn)類似于Pycharm在控制臺輸出中間變量的功能,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2025-03-03
  • 如何利用opencv對拍攝圖片進行文字識別

    如何利用opencv對拍攝圖片進行文字識別

    在有些工程中有時候我們需要對圖片文字識別,下面這篇文章主要給大家介紹了關(guān)于如何利用opencv對拍攝圖片進行文字識別的相關(guān)資料,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2024-03-03
  • python寫日志文件操作類與應用示例

    python寫日志文件操作類與應用示例

    這篇文章主要介紹了python寫日志文件操作類與應用,結(jié)合實例形式分析了Python日志文件操作類的定義與使用相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • Python中zip()函數(shù)的簡單用法舉例

    Python中zip()函數(shù)的簡單用法舉例

    這篇文章主要給大家介紹了關(guān)于Python中zip()函數(shù)的簡單用法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Python具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-09-09
  • python實現(xiàn)在線翻譯

    python實現(xiàn)在線翻譯

    這篇文章主要介紹了python實現(xiàn)在線翻譯,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • Python參數(shù)傳遞中雙星號(**)和單星號(*)是作用

    Python參數(shù)傳遞中雙星號(**)和單星號(*)是作用

    雙星號(**)和單星號(*)在參數(shù)傳遞中扮演著關(guān)鍵角色,本文主要介紹了Python參數(shù)傳遞中雙星號(**)和單星號(*)是作用,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • python 劃分數(shù)據(jù)集為訓練集和測試集的方法

    python 劃分數(shù)據(jù)集為訓練集和測試集的方法

    今天小編就為大家分享一篇python 劃分數(shù)據(jù)集為訓練集和測試集的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12

最新評論

永济市| 江口县| 鹤壁市| 贵港市| 保山市| 天镇县| 安多县| 阳泉市| 尚志市| 兴仁县| 仪征市| 井研县| 理塘县| 平潭县| 南宁市| 永清县| 望江县| 邳州市| 咸丰县| 巩留县| 睢宁县| 新平| 平度市| 青岛市| 龙泉市| 鄱阳县| 台湾省| 永州市| 台中县| 秦安县| 冷水江市| 阿坝县| 阜南县| 米易县| 如皋市| 邳州市| 方山县| 长岛县| 海晏县| 汶上县| 永和县|