【Python 基础全栈·第 03 篇】流程控制:if·for·while·推导式——让程序学会"选择"和"重复"

系列回顾:第 01 篇搭建了 Python 环境,理解了 Python 之禅。第 02 篇掌握了数据类型与运算——int/float/string/bool/类型转换。本篇进入编程的两大基本控制结构——流程控制。程序的本质是"顺序+选择+重复":顺序执行是默认行为,选择(if/match)让程序能根据条件走不同路径,重复(for/while)让程序能批量处理数据。Python 的流程控制有三个核心特点:缩进表示代码块(不用大括号)、for 是 foreach(遍历一切可迭代对象)、推导式替代循环创建(最 Pythonic 的语法)。本篇涵盖四大主题:条件判断(if/elif/else/match/case/三元/海象)、循环(for/while/break/continue/else)、推导式(列表/字典/集合/生成器表达式)、迭代器协议(iter/next/可迭代对象)。实战项目是猜数字游戏——综合运用条件判断、循环、推导式的完整小游戏。


在这里插入图片描述

📑 文章目录


🔀 一、条件判断:if·match·三元·海象

1.1 if/elif/else:条件判断的基础

Python 用 if/elif/else 进行条件判断,用缩进(4个空格)表示代码块,而非大括号。

# 基本条件判断
score = 85

if score >= 90:
    grade = "优秀"
elif score >= 80:
    grade = "良好"
elif score >= 60:
    grade = "及格"
else:
    grade = "不及格"

print(f"成绩: {score}, 等级: {grade}")  # 成绩: 85, 等级: 良好

关键要点

  1. 冒号不能忘:每个条件后面必须有冒号 :
  2. 缩进必须一致:同一代码块的缩进必须相同(推荐4个空格)
  3. elif 不是 else if:Python 用 elif,不是 else if
  4. 不需要括号if x > 0: 不需要写成 if (x > 0):

条件表达式中的真值判断

# Python 的真值判断非常灵活
# 以下值在布尔上下文中为 False(Falsy):
# None, False, 0, 0.0, 0j, "", (), [], {}, set(), range(0)

# Falsy 值判断
name = ""
if not name:  # 等价于 if name == ""
    print("名字为空")

data = []
if not data:  # 等价于 if len(data) == 0
    print("列表为空")

# Truthy 值判断
items = [1, 2, 3]
if items:  # 等价于 if len(items) > 0
    print(f"有 {len(items)} 个元素")

1.2 match/case:模式匹配(Python 3.10+)

Python 3.10 引入了 match/case 语句,类似于其他语言的 switch/case,但功能更强大——支持模式匹配

# 基本模式匹配
command = "quit"

match command:
    case "start":
        print("启动")
    case "stop":
        print("停止")
    case "quit" | "exit":  # 或模式
        print("退出")
    case _:  # 通配符,类似 default
        print(f"未知命令: {command}")

# 解构匹配
point = (3, 4)

match point:
    case (0, 0):
        print("原点")
    case (x, 0):
        print(f"X轴上, x={x}")
    case (0, y):
        print(f"Y轴上, y={y}")
    case (x, y):
        print(f"点({x}, {y})")

# 类匹配
class Circle:
    def __init__(self, radius):
        self.radius = radius

class Rectangle:
    def __init__(self, w, h):
        self.w = w
        self.h = h

shape = Circle(5)

match shape:
    case Circle(r):
        print(f"圆, 半径={r}")
    case Rectangle(w, h):
        print(f"矩形, {w}x{h}")

1.3 三元表达式

Python 的三元表达式(条件表达式)语法:值1 if 条件 else 值2

# 三元表达式
age = 20
status = "成年" if age >= 18 else "未成年"

# 等价于
if age >= 18:
    status = "成年"
else:
    status = "未成年"

# 实际应用:默认值
name = input("姓名: ") or "匿名"  # 空字符串时用默认值

# 实际应用:条件赋值
discount = 0.8 if is_vip else 1.0

注意:三元表达式不要嵌套——嵌套三元可读性极差:

# ❌ 嵌套三元——可读性灾难
result = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 60 else "D"

# ✅ 用 if/elif 代替
if score >= 90:
    result = "A"
elif score >= 80:
    result = "B"
elif score >= 60:
    result = "C"
else:
    result = "D"

1.4 海象运算符 :=(Python 3.8+)

海象运算符(Walrus Operator):= 在表达式中同时赋值和判断,减少重复计算。

# 不用海象——重复计算
n = len(data)
if n > 10:
    print(f"数据太长: {n}")

# 用海象——一步到位
if (n := len(data)) > 10:
    print(f"数据太长: {n}")

# while 循环中的海象
import re
while (line := input(">>> ")) != "quit":
    print(f"你输入了: {line}")

# 列表推导中的海象
results = [y for x in data if (y := expensive_func(x)) is not None]

🔄 二、循环:for·while·break·continue·else

2.1 for 循环:遍历一切

Python 的 for 不是 C 语言的 for(init;cond;inc),而是 foreach——遍历任何可迭代对象。

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

# 遍历字符串
for char in "Python":
    print(char)

# 遍历字典
person = {"name": "张三", "age": 25, "city": "北京"}
for key in person:           # 遍历键
    print(key)
for key, value in person.items():  # 遍历键值对
    print(f"{key}: {value}")

# range() 生成数字序列
for i in range(5):       # 0, 1, 2, 3, 4
    print(i)
for i in range(2, 10, 3):  # 2, 5, 8
    print(i)
for i in range(10, 0, -1):  # 10, 9, ..., 1
    print(i)

2.2 enumerate 和 zip:Pythonic 遍历

enumerate:同时获取索引和值

# ❌ 不 Pythonic
fruits = ["苹果", "香蕉", "橙子"]
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# ✅ Pythonic
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

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

zip:并行遍历多个序列

names = ["张三", "李四", "王五"]
ages = [25, 30, 28]
cities = ["北京", "上海", "深圳"]

# 并行遍历
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, {city}")

# 创建字典
person_dict = dict(zip(names, ages))
# {"张三": 25, "李四": 30, "王五": 28}

# 解包
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
nums, letters = zip(*pairs)
# nums = (1, 2, 3), letters = ('a', 'b', 'c')

2.3 while 循环:条件循环

# 基本while循环
count = 0
while count < 5:
    print(f"计数: {count}")
    count += 1

# 猜数字(while + break)
import random
target = random.randint(1, 100)

while True:
    guess = int(input("猜一个数字(1-100): "))
    if guess == target:
        print("恭喜,猜对了!")
        break
    elif guess < target:
        print("太小了")
    else:
        print("太大了")

2.4 break、continue 和循环 else

# break:提前退出循环
for item in items:
    if item == target:
        print(f"找到了: {item}")
        break  # 找到后立即退出
else:
    print("没找到")  # 循环正常结束时执行

# continue:跳过当前迭代
for i in range(10):
    if i % 2 == 0:
        continue  # 跳过偶数
    print(i)  # 只打印奇数

# 循环 else:循环正常结束时执行(没有被break打断)
for n in range(2, 100):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            break
    else:
        print(f"{n} 是质数")  # 内层循环没被break→质数

✨ 三、推导式与迭代器:Pythonic 的核心语法

3.1 列表推导式

列表推导式(List Comprehension)是 Python 最 Pythonic 的语法之一——用一行代码替代循环+append。

# 基本语法:[表达式 for 项 in 可迭代对象]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件过滤:[表达式 for 项 in 可迭代对象 if 条件]
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 带条件表达式:[值1 if 条件 else 值2 for 项 in 可迭代对象]
labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ["偶数", "奇数", "偶数", "奇数", "偶数"]

# 嵌套推导式(不要超过两层)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

# ❌ 不要过度使用——太复杂就用for循环
# 难以理解的推导式
result = [f(x) for x in data if g(x) > threshold and h(x) is not None]

# ✅ 更清晰的for循环
result = []
for x in data:
    if g(x) <= threshold:
        continue
    if h(x) is None:
        continue
    result.append(f(x))

3.2 字典推导式

# 键值变换
names = ["张三", "李四", "王五"]
name_lengths = {name: len(name) for name in names}
# {"张三": 2, "李四": 2, "王五": 2}

# 反转字典
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
# {1: "a", 2: "b", 3: "c"}

# 从两个列表创建字典
keys = ["name", "age", "city"]
values = ["张三", 25, "北京"]
person = dict(zip(keys, values))
# {"name": "张三", "age": 25, "city": "北京"}

# 条件过滤
scores = {"张三": 85, "李四": 92, "王五": 58, "赵六": 76}
passed = {name: score for name, score in scores.items() if score >= 60}
# {"张三": 85, "李四": 92, "赵六": 76}

3.3 集合推导式

# 提取唯一值
words = ["hello", "world", "hello", "python", "world"]
first_chars = {word[0] for word in words}
# {"h", "w", "p"}

# 数学运算去重
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
mod3 = {n % 3 for n in numbers}
# {0, 1, 2}

3.4 生成器表达式

生成器表达式(Generator Expression)用圆括号 (),惰性求值,节省内存。

# 列表推导式——立即创建所有元素
squares_list = [x**2 for x in range(1000000)]  # 占用大量内存

# 生成器表达式——惰性求值
squares_gen = (x**2 for x in range(1000000))  # 几乎不占内存

# 使用生成器
for sq in squares_gen:
    if sq > 100:
        break
    print(sq)

# 生成器常用场景:sum/max/min/any/all
total = sum(x**2 for x in range(100))  # 不需要创建中间列表
has_negative = any(x < 0 for x in data)
all_positive = all(x > 0 for x in data)
max_len = max(len(s) for s in strings)

3.5 迭代器协议

Python 的迭代器协议是 for 循环的底层机制——任何实现了 __iter__()__next__() 方法的对象都可以被 for 遍历。

# 手动迭代
lst = [1, 2, 3]
it = iter(lst)       # 调用 __iter__()
next(it)              # 1,调用 __next__()
next(it)              # 2
next(it)              # 3
next(it)              # StopIteration 异常

# 自定义迭代器
class Countdown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        self.current -= 1
        return self.current + 1

for n in Countdown(5):
    print(n)  # 5, 4, 3, 2, 1

🎮 实战项目:猜数字游戏

综合运用条件判断、循环、推导式,实现一个完整的猜数字游戏:

import random

class NumberGuessingGame:
    """猜数字游戏——综合运用流程控制"""

    def __init__(self, min_num=1, max_num=100, max_attempts=7):
        self.min_num = min_num
        self.max_num = max_num
        self.max_attempts = max_attempts
        self.history = []  # 历史记录

    def play(self):
        """开始游戏"""
        target = random.randint(self.min_num, self.max_num)
        attempts = 0

        print(f"\n🎯 猜数字游戏!范围: {self.min_num}-{self.max_num}")
        print(f"你有 {self.max_attempts} 次机会\n")

        while attempts < self.max_attempts:
            remaining = self.max_attempts - attempts
            guess_input = input(f"第{attempts+1}次猜测(剩余{remaining}次): ")

            # 输入验证
            if not guess_input.isdigit():
                print("⚠️ 请输入数字!")
                continue

            guess = int(guess_input)
            attempts += 1

            # 记录猜测
            self.history.append({
                'attempt': attempts,
                'guess': guess,
                'hint': 'correct' if guess == target
                        else 'too_low' if guess < target
                        else 'too_high'
            })

            # 条件判断
            if guess == target:
                print(f"🎉 恭喜!{attempts}次猜对了!")
                self._show_stats(target)
                return True
            elif guess < target:
                diff = target - guess
                hint = "差很远" if diff > 30 else "差一些" if diff > 10 else "接近了"
                print(f"📈 太小了!({hint})")
            else:
                diff = guess - target
                hint = "差很远" if diff > 30 else "差一些" if diff > 10 else "接近了"
                print(f"📉 太大了!({hint})")

        print(f"\n😢 游戏结束!答案是 {target}")
        self._show_stats(target)
        return False

    def _show_stats(self, target):
        """显示统计信息——使用推导式"""
        print(f"\n📊 游戏统计:")
        print(f"  目标数字: {target}")

        # 推导式统计
        low_guesses = [h for h in self.history if h['hint'] == 'too_low']
        high_guesses = [h for h in self.history if h['hint'] == 'too_high']

        print(f"  猜小了: {len(low_guesses)}次")
        print(f"  猜大了: {len(high_guesses)}次")

        # 猜测范围缩小
        if low_guesses and high_guesses:
            max_low = max(h['guess'] for h in low_guesses)
            min_high = min(h['guess'] for h in high_guesses)
            print(f"  缩小范围: {max_low+1}-{min_high-1}")

    def show_history(self):
        """显示历史记录"""
        if not self.history:
            print("暂无游戏记录")
            return

        # 字典推导式统计
        stats = {h['hint']: h['guess'] for h in self.history}
        for record in self.history:
            status = {"too_low": "📈小", "too_high": "📉大", "correct": "✅对"}
            print(f"  第{record['attempt']}次: {record['guess']} {status[record['hint']]}")


def main():
    game = NumberGuessingGame()

    while True:
        game.play()

        again = input("\n再玩一次?(y/n): ").lower()
        if again != 'y':
            print("👋 再见!")
            break

        game.history.clear()


if __name__ == '__main__':
    main()

📌 第 03 篇总结

维度 核心内容
条件判断 if/elif/else / match/case(3.10+) / 三元表达式 / 海象运算符
循环 for(遍历) / while(条件) / enumerate(索引) / zip(并行) / break/continue/else
推导式 列表推导 / 字典推导 / 集合推导 / 生成器表达式 / 迭代器协议
实战项目 猜数字游戏——条件判断+循环+推导式综合应用

三大要点

  1. 条件判断:if 是基础,match 是升级(3.10+),三元是简化,海象是优化
  2. 循环:for 遍历一切,enumerate 替代 range(len),推导式替代循环创建
  3. 推导式:列表推导最常用,字典推导键值变换,生成器表达式省内存

第 03 篇的核心 = if(选择) + for(重复) + 推导式(Pythonic创建),流程控制是编程的"骨架"


Python 基础全栈系列进度

篇号 主题 核心内容 状态
01 全景搭建 历史/安装/解释器/IDE/Pythonic
02 类型与运算 数字/字符串/布尔/类型转换/计算器
03 流程控制(本文) if/for/while/推导式/猜数字
04 函数与作用域 参数/返回值/闭包/装饰器/Lambda ⏳ 下一篇
05 数据结构 列表/元组/字典/集合/推导式 待写
06 面向对象 类/继承/多态/封装/魔术方法 待写
07 模块与包 import/pip/虚拟环境/标准库 待写
08 文件与异常 读写/with/异常/上下文管理器 待写
09 高级特性 生成器/迭代器/描述符/元类 待写
10 实战工程 规范/测试/部署/项目结构 待写

下一篇预告:第 04 篇将深入函数与作用域——函数定义/参数类型/返回值/作用域规则/闭包/装饰器/Lambda 表达式,实战项目是任务管理器


参考链接

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐