来源:03_循环 hm_01~hm_07 + Python官方文档 + 网络资料整理


一、详细讲解

1.1 核心概念

while循环是Python编程中的重要知识点,在本课程的第6天我们将系统学习while循环、计数器控制、无限循环、以及while-else结构的完整知识体系。

while循环是一种条件驱动的循环结构,它会在条件为True时反复执行代码块,直到条件变为False为止。这种循环特别适用于迭代次数不确定的场景,比如等待用户输入、读取文件直到结束、或者进行未知次数的搜索操作。

与for循环不同,while循环需要程序员手动管理循环变量,确保循环最终能够终止,否则会产生无限循环。因此,使用while循环时需要格外注意循环条件的设置和计数器变量的更新。

1.2 while循环语法详解

1.2.1 基本语法结构

# while循环的基本语法
while 条件表达式:
    # 循环体 - 当条件为True时执行
    语句块

语法说明:

  • 条件表达式是一个布尔值或可以转换为布尔值的表达式
  • 当条件为True时,执行循环体中的语句
  • 执行完循环体后,会再次评估条件表达式
  • 这个过程重复进行,直到条件变为False

1.2.2 计数循环的实现

# 计数器初始化
counter = 0

# 条件判断
while counter < 5:
    # 循环体
    print(f"计数器当前值: {counter}")
    # 计数器更新 - 这是防止无限循环的关键
    counter += 1

print("循环结束")

运行结果:

计数器当前值: 0 计数器当前值: 1 计数器当前值: 2 计数器当前值: 3 计数器当前值: 4 循环结束

1.3 while循环的执行流程

┌─────────────────┐ │ 初始化计数器 │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 评估条件表达式 │◄──────────┐ └────────┬────────┘ │ │ │ 条件为True? │ │ │ ┌────┴────┐ │ │ │ │ Yes No │ │ │ │ ▼ ▼ │ ┌─────────┐ ┌─────────┐ │ │ 执行循环体│ │ 退出循环 │ │ │ 更新计数器│ └─────────┘ │ └────┬────┘ │ │ │ └────────────────────────┘

1.4 实用示例

1.4.1 1~100累加求和

# 计算1到100的累加和
i = 1        # 初始化计数器,起始值为1
total = 0    # 初始化求和变量

while i <= 100:      # 条件:i小于等于100
    total += i       # 累加当前i的值
    i += 1            # 计数器递增

print(f"1+2+3+...+100 = {total}")  # 输出: 5050

算法分析:

  • 时间复杂度:O(n),其中n=100
  • 空间复杂度:O(1),只使用了两个变量

1.4.2 用户登录验证模拟

# 模拟用户登录验证(最多尝试3次)
max_attempts = 3          # 最大尝试次数
attempts = 0              # 当前尝试次数计数器

while attempts < max_attempts:
    attempts += 1
    password = input(f"请输入密码(第{attempts}次尝试): ")
    
    if password == "python123":
        print("登录成功!")
        break
    else:
        remaining = max_attempts - attempts
        if remaining > 0:
            print(f"密码错误,你还有{remaining}次机会")
        else:
            print("密码错误,账户已被锁定")

1.4.3 猜数字游戏

# 猜数字游戏
import random

target = random.randint(1, 100)  # 系统随机生成的目标数字
guess = 0                         # 用户猜测的数字
max_guesses = 7                   # 最大猜测次数

print("我已经想好了一个1到100之间的数字")
print(f"你有{max_guesses}次猜测机会")

while guess != target and max_guesses > 0:
    guess = int(input("请输入你的猜测: "))
    
    if guess < target:
        print("太小了,再试一次!")
    elif guess > target:
        print("太大了,再试一次!")
    
    max_guesses -= 1
    
    if max_guesses > 0 and guess != target:
        print(f"剩余猜测次数: {max_guesses}")

if guess == target:
    print("恭喜你,猜对了!")
else:
    print(f"很遗憾,正确答案是{target}")

1.5 while-else结构

Python的while循环支持可选的else子句,这是Python相比其他语言的一个独特特性。

1.5.1 语法结构

while 条件表达式:
    # 循环体
    语句块
else:
    # 当循环正常结束(不是因为break跳出)时执行
    else语句块

1.5.2 执行时机说明

# else子句在以下情况会执行:
# 1. 循环条件首次变为False时
# 2. 循环体执行完毕,条件仍为True,但继续判断时发现为False

# else子句在以下情况不会执行:
# 1. 循环被break语句提前终止
# 2. 循环中发生异常(exception)

count = 0
while count < 3:
    print(f"第{count + 1}次循环")
    count += 1
else:
    print("循环正常结束,else子句被执行")

print("---分隔线---")

count = 0
while count < 3:
    print(f"第{count + 1}次循环")
    if count == 1:
        print("遇到break,强制退出")
        break
    count += 1
else:
    print("这一行不会打印,因为循环被break中断")

输出:

第1次循环 第2次循环 第3次循环 循环正常结束,else子句被执行 ---分隔线--- 第1次循环 第2次循环 遇到break,强制退出

1.5.3 while-else的实际应用

# 查找素数的例子
def find_primes_up_to(n):
    """查找小于等于n的所有素数"""
    primes = []
    i = 2
    
    while i <= n:
        is_prime = True
        j = 2
        
        while j * j <= i:
            if i % j == 0:
                is_prime = False
                break
            j += 1
        else:
            # 如果内层循环正常结束(不是因为break)
            # 说明没有找到因子,当前i是素数
            primes.append(i)
        i += 1
    else:
        # 外层循环正常结束
        print(f"查找完成,共找到{len(primes)}个素数")
    
    return primes

result = find_primes_up_to(30)
print(f"30以下的素数: {result}")

1.6 无限循环及其风险

1.6.1 什么是无限循环

当while循环的条件始终为True时,循环将永远不会自动停止,这就是无限循环

# 这是一个无限循环 - 不要轻易尝试!
# while True:
#     print("我会一直运行下去...")

1.6.2 无限循环的常见原因

# 错误示例1:忘记更新计数器
i = 0
while i < 10:
    print(i)
    # 忘记写 i += 1
    # 这会导致无限循环

# 错误示例2:计数器更新位置错误
i = 0
while i < 10:
    i += 1  # 更新在打印之前
    print(i)  # 输出1~10

# 错误示例3:条件永远无法变为False
count = 10
while count >= 0:
    print(count)
    count += 1  # 方向错了,永远不会小于0

1.6.3 如何安全使用无限循环

# 方法1:使用break条件退出
while True:
    user_input = input("输入'quit'退出: ")
    if user_input == 'quit':
        break
    print(f"你输入了: {user_input}")

# 方法2:使用计数器限制
counter = 0
max_iterations = 1000

while True:
    # 业务逻辑
    counter += 1
    if counter >= max_iterations:
        print("达到最大迭代次数,强制退出")
        break

# 方法3:结合异常处理
while True:
    try:
        number = int(input("输入一个数字(输入0退出): "))
        if number == 0:
            print("退出程序")
            break
        print(f"你输入的数字是: {number}")
    except ValueError:
        print("输入无效,请输入一个整数")
        continue  # 继续下一次循环

1.7 计数器模式详解

1.7.1 正向计数

# 正向计数:从start到end
start = 1
end = 10

while start <= end:
    print(start, end=" ")
    start += 1
# 输出: 1 2 3 4 5 6 7 8 9 10

1.7.2 反向计数

# 反向计数:从end到start
start = 1
end = 10

while end >= start:
    print(end, end=" ")
    end -= 1
# 输出: 10 9 8 7 6 5 4 3 2 1

1.7.3 步长控制

# 步长为2的计数
i = 0
while i <= 10:
    print(i, end=" ")
    i += 2
# 输出: 0 2 4 6 8 10

print()

# 自定义步长
start = 1
step = 3
end = 20

while start <= end:
    print(start, end=" ")
    start += step
# 输出: 1 4 7 10 13 16 19

1.8 while循环的嵌套使用

# while循环的嵌套:打印九九乘法表(前3行)
i = 1
while i <= 3:
    j = 1
    line = ""
    while j <= i:
        product = i * j
        line += f"{i}×{j}={product} "
        j += 1
    print(line)
    i += 1

# 输出:
# 1×1=1 
# 1×1=2 2×2=4 
# 1×1=3 2×2=6 3×3=9

1.9 最佳实践与性能优化

1.9.1 避免在循环中重复计算条件

# 低效写法
while len(items) > 0:
    item = items.pop()
    process(item)

# 高效写法
n = len(items)  # 预先计算长度
while n > 0:
    item = items.pop()
    process(item)
    n -= 1

1.9.2 使用局部变量加速访问

# 对于大量迭代,可以使用局部变量
data = list(range(10000))

# 慢:每次都要查询len
i = 0
while i < len(data):
    data[i] *= 2
    i += 1

# 快:使用局部变量
data = list(range(10000))
n = len(data)
i = 0
while i < n:
    data[i] *= 2
    i += 1

1.9.3 循环不变式

保持循环不变式的正确性是编写正确while循环的关键:

# 循环不变式:total始终等于已遍历元素的和
i = 0
total = 0
data = [1, 2, 3, 4, 5]

# 循环不变式在循环开始前为真
while i < len(data):
    # 循环体执行前:total是data[0:i]的和
    total += data[i]
    # 循环体执行后:total是data[0:i+1]的和
    i += 1

# 循环结束后:total是data[0:n]的和,即所有元素的和
print(f"总和: {total}")  # 15

1.10 常见错误与调试技巧

# 错误1:缩进错误
i = 0
while i < 5:
print(i)  # IndentationError: expected an indented block
    i += 1

# 错误2:使用了比较运算符而非赋值
# i = 0
# while i < 5:
#     print(i)
#     i = 5  # 死循环!应该是 i += 1

# 调试技巧:添加日志
debug_mode = True
i = 0
while i < 5:
    if debug_mode:
        print(f"[DEBUG] i={i}, condition={i<5}")
    i += 1

二、背诵版

Day6 要点速记: 【while循环三要素】 1. 初始化计数器 2. 条件判断 3. 更新计数器 【while-else语法】 while 条件: 循环体 else: # 循环正常结束时执行 # break跳出时不执行 【常见错误】 - 忘记更新计数器 → 无限循环 - 计数器更新位置错误 → 逻辑错误 - 条件永远为True → 死循环 【使用场景】 - 迭代次数未知时 - 等待某个条件满足时 - 需要手动控制循环变量时

三、考前记忆

要素 内容
今日主题 while循环基础
关键词 while、计数循环、无限循环、while-else
重要考点 while循环条件控制、else子句执行时机
易错点 忘记更新计数器导致无限循环
语法结构 while 条件: → 循环体 → else:

四、测试题

1. 单选题: 以下哪个是while循环的正确语法?

# 选项A
while i < 10
    print(i)
    i += 1

# 选项B
while (i < 10):
    print(i)
    i += 1

# 选项C
while i < 10 do:
    print(i)
    i += 1

# 选项D
while i < 10
    print(i)
    i += 1

2. 单选题: 以下代码的输出是什么?

count = 0
while count < 3:
    print(count)
    count += 1
else:
    print("done")
  • A. 0 1 2 done
  • B. 0 1 2 3 done
  • C. 0 1 2
  • D. 死循环

3. 判断题: while-else结构中,如果循环被break语句提前终止,else子句会执行。

4. 填空题: while循环中,用于控制循环次数的变量称为 _______。

5. 填空题: 当while循环的条件永远为True时,会产生 _______ 循环。

6. 简答题: 请描述while循环的执行流程,并说明while-else中else子句的执行时机。

7. 代码题: 编写代码,使用while循环计算1+2+3+…+50的结果。

8. 代码题: 编写代码,使用while-else结构查找一个列表中的最大元素。

9. 综合题: 设计一个简单的 ATM 取款模拟程序,要求:

  • 用户有1000元余额
  • 每次取款后显示剩余余额
  • 输入0或余额不足时退出
  1. B - while循环需要冒号,选项A/C/D语法错误

  2. A - count从0开始,输出0,1,2,然后count变为3时条件为False,执行else

  3. - break终止循环时,else子句不会执行

  4. 计数器 - 用于控制循环次数的变量

  5. 无限(死) - 无限循环会导致程序无法正常结束

  6. while循环执行流程:

    • 首先评估条件表达式
    • 若为True,执行循环体,然后再次评估条件
    • 若为False,跳过循环体,执行else子句(如果有)
    • else在循环正常结束(条件首次为False)时执行,因break跳出时不执行
i = 1
total = 0
while i <= 50:
    total += i
    i += 1
print(f"1+2+3+...+50 = {total}")  # 1275
numbers = [3, 7, 2, 9, 4, 1]
if numbers:
    max_val = numbers[0]
    index = 1
    while index < len(numbers):
        if numbers[index] > max_val:
            max_val = numbers[index]
        index += 1
    else:
        print(f"最大元素是: {max_val}")
balance = 1000
print("=== ATM 取款模拟 ===")
print(f"您的余额: {balance}元")

while True:
    amount = int(input("请输入取款金额(输入0退出): "))
    
    if amount == 0:
        print("感谢使用,再见!")
        break
    
    if amount > balance:
        print(f"余额不足!当前余额: {balance}元")
        continue
    
    balance -= amount
    print(f"取款成功!剩余余额: {balance}元")
    
    if balance == 0:
        print("余额已用完,感谢使用!")
        break

五、扩展阅读

5.1 while循环 vs for循环

特性 while循环 for循环
适用场景 迭代次数不确定 迭代次数已知/可迭代对象
循环控制 手动管理计数器 自动管理迭代器
代码复杂度 需要注意计数器更新 更简洁、更安全
灵活性 更高,可实现复杂逻辑 适合遍历操作

5.2 Python 3.10+ 新特性

Python 3.10引入了一些关于循环的改进,但while循环的基本语法保持不变。在现代Python中,推荐使用**海象运算符(:=)**来简化某些while循环:

# Python 3.8+
# 传统写法
line = input("Enter a line: ")
while line != "quit":
    print(f"You entered: {line}")
    line = input("Enter a line: ")

# 使用海象运算符(更简洁)
while (line := input("Enter a line: ")) != "quit":
    print(f"You entered: {line}")

恭喜完成Day6学习!明天我们将学习break和continue语句,掌握更精细的循环控制技巧。