Python: 分支循环实战

学了这么多理论知识,是时候动手做几个像样的项目了。这节是纯实战课,我们将用前面学过的 if 条件判断、for 循环、while 循环、break、continue 等知识,一步步搭建四个完整的程序。

每个项目我们都会先分析思路,再写出代码,最后讨论可能的改进方向。


1. 实战 1:猜数字游戏(增强版)

第 08 课我们写了一个基础的猜数字游戏,现在来给它升级:加入难度选择、猜测次数限制、以及"再来一局"功能。

(1) 需求分析

TEXT 📖 仅展示
1. 玩家选择难度:简单(1-50,无限次)、普通(1-100,10次)、困难(1-200,7次)
2. 系统随机生成目标数字
3. 玩家每次猜测后,提示"大了"或"小了",并显示剩余次数
4. 猜中或次数用尽后,询问"是否再来一局"
5. 输入 q 退出游戏

(2) 完整代码(⭐⭐⭐)

▶ 示例:猜数字游戏

TEXT 📖 仅展示
import random

print("=" * 30)
print("🎯 猜数字游戏(增强版)")
print("=" * 30)

while True:  # 外层循环:控制"再来一局"
    # 选择难度
    print("\n请选择难度:")
    print("1. 简单(1~50,无限次数)")
    print("2. 普通(1~100,10次)")
    print("3. 困难(1~200,7次)")

    choice = input("请输入 1/2/3:")

    if choice == "1":
        max_num = 50
        max_attempts = float("inf")  # 无限次
    elif choice == "2":
        max_num = 100
        max_attempts = 10
    elif choice == "3":
        max_num = 200
        max_attempts = 7
    else:
        print("无效选择,默认普通难度")
        max_num = 100
        max_attempts = 10

    # 生成目标数字
    target = random.randint(1, max_num)
    attempts = 0
    print(f"\n已生成 1~{max_num} 之间的数字,开始猜吧!")

    # 内层循环:游戏主逻辑
    while True:
        # 检查次数是否用尽
        if attempts >= max_attempts:
            print(f"\n😵 次数用尽!正确答案是 {target}")
            break

        # 获取玩家输入
        guess_str = input(f"还剩 {max_attempts - attempts} 次,请输入:")

        if guess_str.lower() == "q":
            print("退出游戏。")
            # 注意:这里 break 只跳出内层循环,需要特殊处理
            max_attempts = -1  # 用标记通知外层循环
            break

        # 验证输入是否为有效数字
        if not guess_str.isdigit():
            print("请输入有效的数字!")
            continue

        guess = int(guess_str)
        attempts += 1

        # 判断大小
        if guess < target:
            print("小了,再大一点!")
        elif guess > target:
            print("大了,再小一点!")
        else:
            print(f"\n🎉 恭喜你猜对了!就是 {target}!")
            print(f"你用了 {attempts} 次猜中。")
            break

    # 检查是否要退出整个程序
    if max_attempts == -1:  # 玩家输入了 q
        break

    # 询问是否再来一局
    again = input("\n再来一局?(y/n):")
    if again.lower() != "y":
        print("感谢游玩,再见!")
        break
💡 设计亮点:外层循环控制"再来一局",内层循环控制"猜数字过程"。通过 max_attempts = -1 这个标记值来解决"内层 break 后外层也要 break"的问题。你也可以用更优雅的方式——把游戏逻辑封装成函数,用 return 一次性退出。



2. 实战 2:九九乘法表(多种样式)

第 08 课我们打印了标准九九乘法表。一个优秀的程序员,应该能灵活控制循环结构,输出任意样式

(1) 样式 1:标准下三角(⭐⭐)

▶ 示例:标准下三角乘法表

PYTHON
print("=== 标准下三角 ===")
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j}", end="\t")
    print()
▶ 试一试

输出:

TEXT 📖 仅展示
=== 标准下三角 ===

(2) 样式 2:完整矩形(⭐⭐)

▶ 示例:完整矩形乘法表

PYTHON
print("=== 完整矩形 ===")
for i in range(1, 10):
    for j in range(1, 10):
        print(f"{j}×{i}={i*j}", end="\t")
    print()
▶ 试一试

输出:

TEXT 📖 仅展示
=== 完整矩形 ===

(3) 样式 3:上三角(⭐⭐⭐)

▶ 示例:上三角乘法表

PYTHON
print("=== 上三角 ===")
for i in range(1, 10):
    # 先打印空白对齐
    for k in range(1, i):
        print(end="\t\t")
    # 再打印乘法算式
    for j in range(i, 10):
        print(f"{i}×{j}={i*j}", end="\t")
    print()
▶ 试一试

输出效果:

TEXT 📖 仅展示
=== 上三角 ===
1×1=1    1×2=2    1×3=3    …    1×9=9
          2×2=4    2×3=6    …    2×9=18
                    3×3=9    …    3×9=27
                               …
                                        9×9=81
💡 关键理解:上三角的难点在于"空白对齐"——每行前面需要留出 (i-1) × 2 个制表符的空位。这就用到了两个内层循环的技巧:第一个内层循环打空白,第二个内层循环打印算式。



3. 实战 3:简易计算器(增强版)

在第 08 课的作业中我们写了一个基础计算器,现在来做增强版:支持连续运算、保存历史记录。

(1) 需求分析

TEXT 📖 仅展示
1. 启动后显示当前结果为 0
2. 用户输入格式: 运算符 数字,例如 "+ 5"
3. 支持的运算符: + - * / ** // % clear exit
4. clear 重置结果为 0
5. exit 退出程序
6. 每次运算后显示当前结果和历史记录

(2) 完整代码(⭐⭐⭐)

▶ 示例:增强版计算器

TEXT 📖 仅展示
print("=" * 40)
print("🧮 增强版计算器")
print("输入格式:运算符 数字,例如:+ 5")
print("支持:+ - * / ** // %")
print("特殊指令:clear(重置) exit(退出)")
print("=" * 40)

result = 0.0
history = []  # 保存运算历史

while True:
    # 显示当前结果
    print(f"\n当前结果:{result}")

    # 获取用户输入
    cmd = input(">>> ").strip()

    # 处理特殊指令
    if cmd.lower() == "exit":
        print("感谢使用!")
        break

    if cmd.lower() == "clear":
        result = 0.0
        history.clear()
        print("已重置为 0")
        continue

    # 解析普通运算指令
    parts = cmd.split()
    if len(parts) != 2:
        print("格式错误!请输入:运算符 数字")
        continue

    op, num_str = parts

    # 验证数字有效性
    if not num_str.replace(".", "").isdigit() or num_str.count(".") > 1:
        print("无效的数字!")
        continue

    num = float(num_str)

    # 执行运算
    old_result = result
    if op == "+":
        result += num
    elif op == "-":
        result -= num
    elif op == "*":
        result *= num
    elif op == "/":
        if num == 0:
            print("错误:除数不能为 0!")
            continue
        result /= num
    elif op == "**":
        result **= num
    elif op == "//":
        if num == 0:
            print("错误:除数不能为 0!")
            continue
        result //= num
    elif op == "%":
        if num == 0:
            print("错误:除数不能为 0!")
            continue
        result %= num
    else:
        print(f"无效运算符:{op}")
        continue

    # 记录历史
    history.append(f"{old_result} {op} {num} = {result}")

    # 显示结果
    print(f"= {result}")

    # 显示最近 3 条历史(如果有的话)
    if len(history) >= 1:
        print("--- 最近记录 ---")
        for item in history[-3:]:
            print(f"  {item}")

运行示例:

TEXT 📖 仅展示
>>> + 10
= 10.0
--- 最近记录 ---
  0.0 + 10.0 = 10.0

>>> * 3
= 30.0
--- 最近记录 ---
  0.0 + 10.0 = 10.0
  10.0 * 3.0 = 30.0

>>> / 0
错误:除数不能为 0!

>>> clear
已重置为 0
💡 编程思维:这个示例展示了"循环+条件判断"的经典配合——while True 保持程序持续运行,用 if-elif-else 处理各种输入情况,用 continue 跳过无效输入,用 break 正常退出。



4. 实战 4:质数查找器

让用户输入一个范围,输出该范围内所有的质数,并统计个数。

(1) 需求分析

TEXT 📖 仅展示
1. 用户输入起始值和结束值
2. 程序输出该范围内所有的质数
3. 每行显示 10 个,整齐排列
4. 最后显示质数的总个数

(2) 完整代码(⭐⭐⭐)

▶ 示例:质数查找器

PYTHON
print("🔢 质数查找器")
print("输入一个范围,我将找出其中的所有质数。")

# 获取范围
start_str = "2"  # 演示用固定值
end_str = "50"  # 演示用固定值

# 验证输入
if not (start_str.isdigit() and end_str.isdigit()):
    print("请输入有效的正整数!")
else:
    start = int(start_str)
    end = int(end_str)

    if start < 2:
        start = 2
        print("起始值已调整为 2(质数从 2 开始)")

    if start > end:
        print("起始值不能大于结束值!")
    else:
        primes = []  # 存放找到的质数

        # 遍历范围内的每个数
        for num in range(start, end + 1):
            # 判断 num 是否为质数
            is_prime = True
            for i in range(2, int(num ** 0.5) + 1):
                if num % i == 0:
                    is_prime = False
                    break

            if is_prime:
                primes.append(num)

        # 输出结果
        print(f"\n在 {start} ~ {end} 之间,共找到 {len(primes)} 个质数:")

        for i, prime in enumerate(primes, 1):
            print(f"{prime:5d}", end="")
            if i % 10 == 0:  # 每 10 个换行
                print()

        print()  # 最后换行
▶ 试一试

运行示例:

TEXT 📖 仅展示
起始值(≥2):50
结束值:200

在 50 ~ 200 之间,共找到 34 个质数:
   53   59   61   67   71   73   79   83   89   97
  101  103  107  109  113  127  131  137  139  149
  151  157  163  167  173  179  181  191  193  197
  199
💡 优化技巧:判断质数时,不需要除到 num-1,只需要除到 √num 就可以了。因为如果 num 有一个大于 √num 的因子,那必然有一个小于 √num 的因子成对存在。这种优化在处理大范围(比如 10 万以上)时效果非常明显。



5. 实战 5:BMI 健康指数 + 密码强度检测

这个实战把算术运算、比较运算、逻辑运算、条件判断、字符串方法全部串起来,解决两个生活中常见的问题。

(1) 第一部分:BMI 健康指数(⭐⭐)

BMI(Body Mass Index,身体质量指数)是国际上常用的衡量人体胖瘦程度的指标。公式很简单:

BMI = 体重(kg) ÷ 身高(m)²

▶ 示例:BMI 健康指数

PYTHON
# BMI 健康指数计算器

# 输入数据
weight = 68
height = 1.75

# 计算 BMI
bmi = weight / (height ** 2)

print("=== BMI 健康指数 ===")
print(f"您的体重:{weight} kg")
print(f"您的身高:{height} m")
print(f"您的BMI:{bmi:.1f}")

# 用链式比较和 if-elif 判断等级
if bmi < 18.5:
    print("判定:偏瘦")
elif 18.5 <= bmi < 24:
    print("判定:正常 👍")
elif 24 <= bmi < 28:
    print("判定:偏胖 ⚠️")
else:
    print("判定:肥胖 🔴")
▶ 试一试

运行结果:

TEXT 📖 仅展示
=== BMI 健康指数 ===
您的体重:68 kg
您的身高:1.75 m
您的BMI:22.2
判定:正常 👍
💡 这里自动用了链式比较 18.5 <= bmi < 24,是不是比写成 bmi >= 18.5 and bmi < 24 清爽很多?

(2) 第二部分:密码强度检测(⭐⭐⭐)

写个程序来判断用户设置的密码安不安全。一个密码的强度取决于它的长度包含的字符类型

▶ 示例:密码强度检测

PYTHON
# 密码强度检测器

password = "Py3#thon"

# 统计密码的各种特征
length = len(password)                  # 长度
has_digit = any(c.isdigit() for c in password)     # 是否包含数字
has_letter = any(c.isalpha() for c in password)    # 是否包含字母
has_special = not password.isalnum()               # 是否有特殊字符

print("=== 密码强度检测 ===")
print(f"密码:{password}")
print(f"长度:{length}")
print(f"包含数字:{has_digit}")
print(f"包含字母:{has_letter}")
print(f"包含特殊字符:{has_special}")

# 用逻辑运算符组合条件来判断强度
if length < 6:
    strength = "弱"
elif length >= 10 and has_digit and has_letter and has_special:
    strength = "强"
elif length >= 8 and has_digit and has_letter:
    strength = "中"
else:
    strength = "弱"

print(f"密码强度:{strength}")
▶ 试一试

运行结果:

TEXT 📖 仅展示
=== 密码强度检测 ===
密码:Py3#thon
长度:8
包含数字:True
包含字母:True
包含特殊字符:True
密码强度:中
💡 涉及的细节len() 获取字符串长度,isdigit() 判断是否为数字,isalpha() 判断是否为字母,isalnum() 判断是否只包含字母和数字(如果包含特殊字符就返回 False,用 not 取反就是 "包含特殊字符")。这些方法在后面的字符串课会系统学习。



6. 🐛 分支循环常见错误

写代码难免出错,特别是刚学循环的时候。下面几个是最典型的"坑",每个初学者都会踩到。

(1) 错误 1:死循环——忘了更新条件变量

PYTHON
# ❌ 错误写法
n = 1
while n <= 10:
    print(n)
    # 忘了 n += 1 —— 永远跑不完

# ✅ 正确写法
n = 1
while n <= 10:
    print(n)
    n += 1

(2) 错误 2:=== 弄混

TEXT 📖 仅展示
# ❌ 错误写法
if score = 100:  # 这是赋值,不是比较!
    print("满分!")

# ✅ 正确写法
if score == 100:
    print("满分!")

(3) 错误 3:循环内修改正在遍历的列表

PYTHON
# ❌ 错误写法 —— 遍历时删除元素会导致"跳过"
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)
print(numbers)  # 可能不是你想的结果

# ✅ 正确写法 —— 创建新列表
numbers = [1, 2, 3, 4, 5]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)

(4) 错误 4:range() 的结束值理解错

PYTHON
# ❌ 以为 range(5) 会输出 1 2 3 4 5
for i in range(5):
    print(i)  # 实际输出: 0 1 2 3 4

# ✅ 正确写法
for i in range(1, 6):
    print(i)  # 输出: 1 2 3 4 5


7. 常见应用场景

场景 使用的循环/分支技巧 说明
数据处理(过滤、清洗) for + continue 跳过无效数据
用户交互菜单 while True + break 反复显示菜单直到选择退出
分页加载 while + 条件判断 直到没有更多数据
搜索/查找 for + break + else 找到即停,找不到则执行 else
批量文件处理 for + 嵌套逻辑 遍历目录中的每个文件
游戏主循环 while True + 事件处理 持续渲染和响应输入

❓ 常见问题

Q 写循环时总是死循环怎么办?
A 检查三点:① 循环条件会不会在某时刻变 False?② 循环体有没有修改条件相关变量?③ while True 有没有对应的 break?在代码里加 print() 输出关键变量值,是调试死循环最有效的方法。
Q range() 和列表直接遍历,哪个效率高?
A range() 返回惰性序列,不一次性生成所有数字,range(1000000) 几乎不占内存;list(range(1000000)) 会占用大量内存。循环次数大时直接用 range() 更省内存。
Q 实战项目中的代码比之前的示例长很多,怎么读?
A 三步走:先看整体结构(几个循环/条件);再理解主体流程(变量怎么变化);最后关注边界情况(输入验证、除零等)。好的代码应该是自文档化的——变量名有意义、关键处有注释。

📖 小节


📝 作业

⭐ 第一题:水仙花数

"水仙花数"是指一个三位数,其各位数字的立方和等于该数本身。例如:153 = 1³ + 5³ + 3³

请用 for 循环找出所有的水仙花数(共 4 个)。

提示:用 range(100, 1000) 遍历所有三位数,用 //% 分解百位、十位、个位。

⭐⭐ 第二题:打印菱形

接收用户输入一个奇数 n,在控制台输出一个由 * 组成的菱形。

示例(n=5):

TEXT 📖 仅展示
  *
 ***
*****
 ***
  *

提示:菱形由上下两部分组成。上半部分 i 从 1 到 n//2 + 1,空格数递减,星号数递增。

⭐⭐⭐ 第三题:学生成绩管理系统

编写一个程序,实现以下功能:

TEXT 📖 仅展示
1. 输入学生成绩(输入 q 结束输入)
2. 计算总分、平均分、最高分、最低分
3. 统计各分数段人数:90-100(优秀)、80-89(良好)、70-79(中等)、60-69(及格)、<60(不及格)
4. 输出成绩排名(从高到低)

要求:

参考输出:

TEXT 📖 仅展示
请输入学生成绩(输入 q 结束):
第 1 位学生成绩:85
第 2 位学生成绩:92
第 3 位学生成绩:67
第 4 位学生成绩:78
第 5 位学生成绩:55
第 6 位学生成绩:q

===== 成绩统计 =====
总人数:5
总分:377.0
平均分:75.4
最高分:92.0
最低分:55.0

===== 分数段分布 =====
优秀(90-100):1 人
良好(80-89):1 人
中等(70-79):1 人
及格(60-69):1 人
不及格(<60):1 人

===== 成绩排名 =====
92  85  78  67  55

这个项目综合运用了循环、列表、排序、统计等知识,完成它你就真正掌握了 Python 的基础控制流。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏