来源: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或余额不足时退出
-
B - while循环需要冒号,选项A/C/D语法错误
-
A - count从0开始,输出0,1,2,然后count变为3时条件为False,执行else
-
✗ - break终止循环时,else子句不会执行
-
计数器 - 用于控制循环次数的变量
-
无限(死) - 无限循环会导致程序无法正常结束
-
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语句,掌握更精细的循环控制技巧。