🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术

学习路径:Python_AIGC · Day 4

控制流是程序的骨架。Python 用简洁优雅的语法实现了强大的条件判断、循环迭代和推导式。


一、条件判断:if / elif / else

Python 没有 switch/case,但 if/elif/else 已经足够灵活。

python 复制代码
score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"      # 85 走这个分支
elif score >= 70:
    grade = "C"
else:
    grade = "D"

print(grade)  # B

条件表达式(三元运算符)

python 复制代码
age = 20
status = "成年" if age >= 18 else "未成年"
print(status)  # 成年

# 可以嵌套,但不建议(可读性差)
tag = "老人" if age > 60 else ("中年" if age > 35 else "青年")

短路求值

Python 的逻辑运算符 and / or 具有短路特性

python 复制代码
# or 短路:a 为真则整个表达式为 a,不再计算 b
name = input("输入名字: ") or "匿名用户"
# 如果输入为空字符串(falsy),则返回"匿名用户"

# and 短路:a 为假则整个表达式为 a,不再计算 b
def get_config():
    print("读取配置...")
    return {"debug": True}

config = None
result = config and get_config()  # config 为 None(falsy),短路,不会调用函数
print(result)  # None

判断 falsy 值的正确姿势

Python 的 falsy 值:None00.0""[](){}set()False

python 复制代码
items = []

# ❌ 不推荐:显式比较
if len(items) > 0:
    print("有元素")

# ✅ 推荐:利用隐式布尔转换
if items:  # 空列表为 False,非空为 True
    print("有元素")

# ✅ 检查 None 时用 is
value = None
if value is None:
    print("是 None")

# 区分 None 和 0/空字符串
count = 0  # 有效的计数
if count:          # ❌ 0 为 falsy,会被忽略
    print(f"计数: {count}")

if count is not None:  # ✅ 明确检查 None
    print(f"计数: {count}")  # 计数: 0

二、循环:for 和 while

for 循环 --- Python 的主力

python 复制代码
# 遍历可迭代对象
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# enumerate:同时获取索引和值
for idx, fruit in enumerate(fruits, start=1):  # start 可自定义起始
    print(f"{idx}. {fruit}")

# range:数字序列
for i in range(5):       # 0, 1, 2, 3, 4
    pass
for i in range(2, 8):    # 2, 3, 4, 5, 6, 7
    pass
for i in range(0, 10, 2):  # 0, 2, 4, 6, 8
    pass

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

zip:并行遍历

python 复制代码
names = ["Alice", "Bob", "Charlie"]
scores = [88, 92, 78]

for name, score in zip(names, scores, strict=True):
    print(f"{name}: {score}")
# strict=True 要求长度一致,否则抛 ValueError(Python 3.10+)

while 循环

python 复制代码
# 典型用法:直到满足条件
import random

target = random.randint(1, 100)
guess = None
attempts = 0

while guess != target:
    guess = int(input("猜一个数 (1-100): "))
    attempts += 1
    if guess < target:
        print("小了")
    elif guess > target:
        print("大了")

print(f"猜对了!用了 {attempts} 次")

break / continue / else 子句

python 复制代码
# break:提前退出循环
for n in range(2, 20):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            break  # 不是质数,跳出内层循环
    else:
        # ❗ else 子句:循环没有被 break 时执行
        print(f"{n} 是质数")

# continue:跳过当前迭代
for i in range(10):
    if i % 2 == 0:
        continue  # 跳过偶数
    print(i, end=" ")  # 1 3 5 7 9

# ⚠️ 死循环风险
i = 0
while True:
    i += 1
    if i > 1000000:
        break  # 必须确保能退出

🔑 关键点for...elseelse 在循环正常结束(未被 break)时执行。常用于搜索任务。


三、推导式 --- Python 的灵魂语法

推导式(Comprehension)是 Python 最简洁强大的特性之一。

列表推导式

python 复制代码
# 基础:new_list = [expression for item in iterable if condition]
squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 双重循环 --- 扁平化
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 带条件的三元表达式
nums = [-2, -1, 0, 1, 2]
labels = ["正" if n > 0 else ("负" if n < 0 else "零") for n in nums]
# ['负', '负', '零', '正', '正']

字典推导式

python 复制代码
# {key_expr: value_expr for item in iterable}
words = ["hello", "world", "python"]
lengths = {word: len(word) for word in words}
# {'hello': 5, 'world': 5, 'python': 6}

# 条件过滤 + 值变换
scores = {"Alice": 88, "Bob": 55, "Charlie": 72}
passed = {name: score for name, score in scores.items() if score >= 60}
# {'Alice': 88, 'Charlie': 72}

# 键值互换(需确保值可哈希且唯一)
inverse = {v: k for k, v in {"a": 1, "b": 2}.items()}
# {1: 'a', 2: 'b'}

集合推导式

python 复制代码
nums = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in nums}
# {1, 4, 9, 16} --- 自动去重

⚠️ 性能对比

python 复制代码
import timeit

# 列表推导式 vs for 循环
setup = "nums = list(range(1000))"

for_loop = """
result = []
for x in nums:
    if x % 2 == 0:
        result.append(x ** 2)
"""

comprehension = """
result = [x ** 2 for x in nums if x % 2 == 0]
"""

print(timeit.timeit(for_loop, setup, number=10000))        # ~0.45s
print(timeit.timeit(comprehension, setup, number=10000))     # ~0.30s ✅ 快 30-40%

推导式更快:因为底层用 C 级别的循环代替了 Python 字节码的逐条执行。


四、实战:FizzBuzz + 控制流综合

python 复制代码
# 经典 FizzBuzz --- 控制流全家桶
def fizzbuzz(n: int) -> list[str]:
    """1 到 n,3的倍数→Fizz,5的倍数→Buzz,同时→FizzBuzz"""
    result = []
    for i in range(1, n + 1):
        if i % 15 == 0:       # 等效 i % 3 == 0 and i % 5 == 0
            result.append("FizzBuzz")
        elif i % 3 == 0:
            result.append("Fizz")
        elif i % 5 == 0:
            result.append("Buzz")
        else:
            result.append(str(i))
    return result

# 一行版(不推荐生产用)
fizzbuzz_oneliner = [
    "FizzBuzz" if i % 15 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else str(i)
    for i in range(1, 101)
]

print(fizzbuzz(15))
# ['1', '2', 'Fizz', '4', 'Buzz', 'Fizz', '7', '8', 'Fizz', 'Buzz', '11', 'Fizz', '13', '14', 'FizzBuzz']

📝 避坑指南

陷阱 说明 正确做法
is== 混用 is 比较身份,== 比较值 判 None 用 is,其他用 ==
修改遍历中的列表 遍历时增删元素导致意外行为 遍历副本 list[:] 或新建列表
推导式嵌套过深 可读性急剧下降 超过两层循环改用普通 for
else 子句误解 以为 for...else 的 else 是「否则」 实际是「没被 break 时执行」
python 复制代码
# ❌ 遍历时删除
items = [1, 2, 3, 4, 5]
for item in items:
    if item % 2 == 0:
        items.remove(item)  # 跳过元素!
print(items)  # [1, 3, 5] --- 看起来对了?试试 [1, 2, 2, 3, 4] 就翻车

# ✅ 正确做法
items = [1, 2, 3, 4, 5]
items = [x for x in items if x % 2 != 0]  # 重建

Day 4 总结 :控制流是代码的骨架。重点是掌握 for...else 的语义、推导式的性能优势、短路求值的妙用,以及常见的遍历陷阱。

相关推荐
2601_953720822 小时前
【计算机毕业设计】基于Vue与Spring Boot的高校兼职信息服务平台设计与实现
spring boot·后端·课程设计
再吃一根胡萝卜3 小时前
用 Rust 写一个桌面悬浮图标:为什么它比 Python 更适合 AI 桌面工具?
后端
IT_陈寒3 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
大鹏说大话4 小时前
从爬虫到决策引擎:大数据下自媒体如何用Python挖掘用户痛点
开发语言·爬虫·python
Niuguangshuo4 小时前
silero-vad:超轻量级开源 VAD 实践指南
开发语言·python
evans在进步4 小时前
Spring Boot 核心机制详解:可执行 JAR、CORS、静态资源与配置绑定
spring boot·后端·jar
2501_944676164 小时前
揭秘!WORDTIP公司靠不靠谱?小白必看
大数据·人工智能·python
Sayuanni%34 小时前
SpringBoot 从注解到源码:核心知识点总结
java·spring boot·后端
Minner-Scrapy5 小时前
Scrapy 2.17 源码解析:Scheduler 调度器与磁盘/内存双队列
java·爬虫·python·scrapy·网络爬虫·twisted