Python 从入门到实战(四):循环结构(让程序自动批量处理数据)

文章目录
- 一、为什么需要循环?先看一个痛点场景
- 二、for 循环:遍历 “已知序列” 的神器
- 1. 基础用法:遍历列表、元组、字符串
- 2. 进阶用法:用 range () 生成数值序列
- ▶ 用法 1:range (结束值)—— 从 0 到 “结束值 - 1”
- ▶ 用法 2:range (开始值,结束值)—— 从开始值到 “结束值 - 1”
- ▶ 用法 3:range (开始值,结束值,步长)—— 指定间隔
- 3. 高效写法:列表推导式(一行生成列表)
- 4. 新手必踩坑:循环中的缩进错误
- 三、while 循环:“直到满足条件才停止” 的重复动作
- 四、循环与列表结合:批量处理数据的实战场景
- 五、综合实操:学生成绩统计系统
- 六、小结与下一篇预告
欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们学会了用列表和元组存储多个数据 —— 比如一个班级的学生名单、一组考试成绩。但如果要对这些数据做批量处理(比如给每个学生发问候语、计算所有成绩的平均分),手动写代码处理每一个元素简直是 “重复劳动”(比如 100 个学生要写 100 行 print?)。
今天咱们要学 Python 的 “自动化神器”——循环结构。循环就像 “自动分拣机”,能帮你逐个处理列表、元组里的每一个元素,不用重复写代码。Python 里最核心的两种循环是for循环和while循环:for循环适合 “已知要处理的所有元素”(比如遍历列表里的 10 个学生),while循环适合 “直到满足条件才停止”(比如一直接收用户输入直到输入 “退出”)。
接下来咱们从实际场景出发,一步步掌握循环的用法,让你的程序真正 “自动化” 起来。
一、为什么需要循环?先看一个痛点场景
假设你用列表存了 5 个学生的名字,要给每个学生打印一句问候语。用之前的知识,你可能会这么写:
python
运行
# 用列表存储学生名字
students = ["张三", "李四", "王五", "赵六", "孙七"]
# 手动打印每个学生的问候语(重复劳动!)
print(f"你好,{students[0]}!")
print(f"你好,{students[1]}!")
print(f"你好,{students[2]}!")
print(f"你好,{students[3]}!")
print(f"你好,{students[4]}!")
这段代码能运行,但有两个大问题:
- 重复代码多:5 个学生要写 5 行 print,100 个学生就要写 100 行;
- 灵活性差:如果列表新增了学生,必须手动加一行 print。
而用for循环,只需 3 行代码,不管列表有 10 个还是 100 个学生,都能自动处理:
python
运行
students = ["张三", "李四", "王五", "赵六", "孙七"]
# for循环自动遍历每个学生
for student in students:
print(f"你好,{student}!")
运行结果和手动写 5 行 print 完全一样:
plaintext
你好,张三!
你好,李四!
你好,王五!
你好,赵六!
你好,孙七!
这就是循环的核心价值:把重复操作交给程序自动完成,减少代码冗余,提高灵活性。接下来咱们先学for循环,再学while循环。
二、for 循环:遍历 “已知序列” 的神器
for循环的核心是 “遍历序列”—— 序列可以是列表、元组、字符串,甚至是后面会学的字典。它的逻辑就像 “逐个检查抽屉里的每一件东西”:从序列的第一个元素开始,逐个取出来处理,直到所有元素都处理完。
1. 基础用法:遍历列表、元组、字符串
for循环的基本语法很简单:
python
运行
for 临时变量 in 序列:
循环体(要重复执行的代码,注意缩进)
- 临时变量:每次从序列里取出的元素会存在这里(比如遍历学生列表时,临时变量
student依次等于 “张三”“李四”); - 序列:要处理的列表、元组等;
- 循环体:每次取元素后要执行的代码(必须缩进,否则会报错)。
咱们用三个常见场景演示:
▶ 场景 1:遍历列表(最常用)
遍历学生列表,不仅打印问候语,还能结合之前学的字符串方法做格式处理:
python
运行
# 存储学生名单(包含大小写不规范的名字)
students = ["zhangsan", "Li Si", "wang wu"]
# for循环遍历,统一格式后打印
for student in students:
# 首字母大写(title()方法)
formatted_name = student.title()
print(f"欢迎 {formatted_name} 加入班级!")
运行结果:
plaintext
欢迎 Zhangsan 加入班级!
欢迎 Li Si 加入班级!
欢迎 Wang Wu 加入班级!
这里的临时变量student每次取列表里的一个元素,直到所有元素处理完,循环自动结束。
▶ 场景 2:遍历元组
元组和列表用法类似,for循环遍历方式完全相同。比如遍历一周的天数(元组存储,固定不变):
python
运行
# 用元组存储一周的天数(固定不变,适合用元组)
week_days = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")
# 遍历元组,打印每天的计划
print("本周学习计划:")
for day in week_days:
if day in ["周六", "周日"]:
print(f"{day}:复习本周内容")
else:
print(f"{day}:学习新知识点")
运行结果(节选):
plaintext
本周学习计划:
周一:学习新知识点
周二:学习新知识点
...
周六:复习本周内容
周日:复习本周内容
这里提前用了if判断(下一篇会详细讲),让循环能根据不同元素做不同处理,体现循环的灵活性。
▶ 场景 3:遍历字符串(逐个取字符)
字符串也是一种序列,for循环能逐个取出每个字符。比如检查一个字符串里有多少个 “a”:
python
运行
# 要检查的字符串
text = "Python is an easy and powerful language."
# 计数器:记录"a"出现的次数
a_count = 0
# 遍历字符串,统计"a"的个数
for char in text:
if char == "a":
a_count += 1 # 每找到一个"a",计数器加1
print(f"字符串中'a'出现的次数:{a_count}") # 输出:字符串中'a'出现的次数:3
这个例子展示了循环的 “累加” 场景 —— 通过临时变量char逐个检查每个字符,配合计数器统计结果,这在数据统计中很常用。
2. 进阶用法:用 range () 生成数值序列
除了遍历已有的列表 / 元组,for循环还常用来处理 “数值”(比如计算 1 到 100 的总和)。这时候需要range()函数帮忙 —— 它能生成一个 “数值序列”,不用手动写列表[1,2,3,...]。
range()有三种常用用法,咱们逐个讲:
▶ 用法 1:range (结束值)—— 从 0 到 “结束值 - 1”
只传一个参数时,range(n)生成0,1,2,...,n-1的序列(注意不包含 n)。比如range(5)生成0,1,2,3,4:
python
运行
# 生成0~4的数值序列,打印每个数
for num in range(5):
print(num) # 输出:0 1 2 3 4(每行一个)
适合需要 “从 0 开始计数” 的场景,比如统计循环执行次数。
▶ 用法 2:range (开始值,结束值)—— 从开始值到 “结束值 - 1”
传两个参数时,range( start, end)生成start, start+1, ..., end-1的序列。比如range(1,6)生成1,2,3,4,5:
python
运行
# 生成1~5的序列,计算总和
total = 0
for num in range(1, 6):
total += num # 累加:0+1=1 → 1+2=3 → 3+3=6 → 6+4=10 → 10+5=15
print(f"1到5的总和:{total}") # 输出:1到5的总和:15
这个场景很实用,比如计算学生成绩的总分(后面综合实操会用到)。
▶ 用法 3:range (开始值,结束值,步长)—— 指定间隔
传三个参数时,range(start, end, step)生成 “从 start 开始,每次加 step,直到小于 end” 的序列。比如range(2,11,2)生成偶数2,4,6,8,10:
python
运行
# 生成2~10的偶数,计算它们的平方和
square_sum = 0
for even_num in range(2, 11, 2):
square = even_num ** 2 # 计算平方
square_sum += square
print(f"{even_num}的平方:{square}")
print(f"2~10偶数的平方和:{square_sum}") # 输出:2~10偶数的平方和:220
步长也可以是负数(倒序),比如range(10, 0, -2)生成10,8,6,4,2,适合倒序处理数据。
3. 高效写法:列表推导式(一行生成列表)
用for循环生成列表时,Python 提供了一种更简洁的写法 ——列表推导式,能把 “循环 + 添加元素” 的代码压缩成一行,效率更高。
比如要生成 1~10 的平方列表,用普通for循环需要 3 行:
python
运行
# 普通for循环:生成1~10的平方列表
squares = []
for num in range(1, 11):
squares.append(num ** 2)
print(squares) # 输出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
用列表推导式只需 1 行:
python
运行
# 列表推导式:一行生成平方列表
squares = [num ** 2 for num in range(1, 11)]
print(squares) # 输出和上面一样
列表推导式的语法是[表达式 for 临时变量 in 序列]:
- 表达式:每个元素要做的处理(比如
num**2计算平方); - 后面的
for部分和普通循环一样。
再举一个场景:从列表中筛选出大于 60 的成绩,生成新列表:
python
运行
# 原始成绩列表
scores = [85, 58, 92, 76, 45, 88]
# 列表推导式:筛选及格成绩(>60)
passed_scores = [score for score in scores if score > 60]
print(passed_scores) # 输出:[85, 92, 76, 88]
这里加了if条件(下一篇详讲),让推导式更灵活。新手不用急着熟练掌握,但要能看懂,因为后面看别人的代码会经常遇到。
4. 新手必踩坑:循环中的缩进错误
Python 靠缩进来识别 “哪些代码属于循环体”,缩进错了会导致逻辑错误,甚至报错。咱们看两个常见错误:
▶ 错误 1:循环体没缩进(代码不重复执行)
python
运行
# 错误示例:print没缩进,只执行一次
students = ["张三", "李四"]
for student in students:
print(f"你好,{student}!") # 报错:IndentationError: expected an indented block
原因:for语句后面的代码必须缩进(通常 4 个空格),否则 Python 不知道这是循环体。正确写法是给print缩进:
python
运行
# 正确示例
students = ["张三", "李四"]
for student in students:
print(f"你好,{student}!") # 缩进4个空格,循环两次
▶ 错误 2:多余缩进(代码不该循环却循环)
python
运行
# 错误示例:print_total没缩进,不该循环却循环了
scores = [85, 92, 76]
total = 0
for score in scores:
total += score
print(f"当前总分:{total}") # 每次循环都打印(本应循环结束后打印)
# 正确示例:print_total不缩进,只打印一次
scores = [85, 92, 76]
total = 0
for score in scores:
total += score
print(f"最终总分:{total}") # 不缩进,循环结束后打印:最终总分:253
总结:只有 “每次循环都要执行的代码” 才缩进,循环结束后执行的代码不缩进。
三、while 循环:“直到满足条件才停止” 的重复动作
for循环适合 “已知要处理的所有元素”,而while循环适合 “不知道要重复多少次,直到满足某个条件才停止”。比如:
- 让用户反复输入内容,直到输入 “退出”;
- 不断生成游戏敌人,直到玩家生命值为 0。
while循环的核心是 “条件判断”:只要条件为True,就重复执行循环体;条件为False时,循环停止。
1. 基本用法:计数器控制循环次数
最常见的while循环是用 “计数器” 控制次数,比如从 1 数到 5:
python
运行
# 初始化计数器:从1开始
current_num = 1
# while循环:只要current_num <=5,就继续执行
while current_num <= 5:
print(current_num)
current_num += 1 # 计数器更新(必须写!否则无限循环)
运行结果:
plaintext
1
2
3
4
5
这里有两个关键点:
- 初始计数器:循环开始前要给计数器赋值(比如
current_num=1); - 更新计数器:循环体里必须更新计数器(比如
current_num +=1),否则计数器永远不变,条件一直为True,导致无限循环(新手最常踩的坑!)。
2. 控制流程:break、continue 与标志位
有时候需要在循环中灵活控制:比如找到目标元素就停止循环(break)、跳过某个元素(continue)、多个条件控制循环(标志位)。咱们逐个讲:
▶ 用 break:找到目标就停止循环
break的作用是 “立即退出整个循环”,不管后续还有多少元素。比如在成绩列表中找第一个不及格的成绩,找到就停止:
python
运行
scores = [85, 58, 92, 76, 45]
# 找第一个不及格的成绩(<60)
for score in scores:
if score < 60:
print(f"找到第一个不及格成绩:{score}")
break # 找到后立即退出循环,不再检查后面的76和45
print(f"当前成绩及格:{score}")
运行结果:
plaintext
当前成绩及格:85
找到第一个不及格成绩:58
可以看到,找到 58 后,循环直接停止,后面的 76 和 45 没有被检查 —— 这就是break的作用,避免不必要的循环,提高效率。
▶ 用 continue:跳过当前元素,继续下一次循环
continue的作用是 “跳过当前循环体剩下的代码,直接开始下一次循环”。比如遍历成绩列表,只打印及格的成绩,跳过不及格的:
python
运行
scores = [85, 58, 92, 76, 45]
# 只打印及格成绩(>60)
for score in scores:
if score < 60:
continue # 跳过不及格成绩,不执行后面的print
print(f"及格成绩:{score}")
运行结果:
plaintext
及格成绩:85
及格成绩:92
及格成绩:76
58 和 45 因为不及格,被continue跳过,没有打印 ——continue和break的区别是:continue只跳过当前次,break退出整个循环。
▶ 用标志位:多个条件控制循环
当循环需要判断多个条件时(比如游戏中 “玩家没退出” 且 “生命值 > 0” 才继续),用标志位(一个布尔变量)会更清晰。标志位通常命名为active,初始为True,满足某个条件时设为False,循环停止。
比如模拟游戏循环:
python
运行
# 初始化标志位:游戏开始时为活跃状态
active = True
player_health = 100 # 玩家生命值
while active:
# 模拟玩家操作:输入"attack"攻击,"quit"退出
action = input("请输入操作(attack/quit):")
if action == "quit":
active = False # 输入quit,标志位设为False,循环停止
print("你退出了游戏!")
elif action == "attack":
player_health -= 20 # 每次攻击消耗20生命值
print(f"攻击成功!当前生命值:{player_health}")
if player_health <= 0:
active = False # 生命值为0,标志位设为False,循环停止
print("生命值耗尽,游戏结束!")
else:
print("无效操作,请重新输入!")
运行示例:
plaintext
请输入操作(attack/quit):attack
攻击成功!当前生命值:80
请输入操作(attack/quit):attack
攻击成功!当前生命值:60
请输入操作(attack/quit):quit
你退出了游戏!
用标志位后,不管是 “玩家主动退出” 还是 “生命值耗尽”,只要active变为False,循环就停止,逻辑更清晰。
3. 避坑:如何避免无限循环?
无限循环是新手最头疼的问题 —— 循环永远不停止,只能按Ctrl+C强制结束。咱们先看一个无限循环的例子,再讲如何避免:
▶ 无限循环示例(计数器没更新)
python
运行
# 错误示例:忘记更新计数器,current_num永远是1
current_num = 1
while current_num <= 5:
print(current_num)
# 没写current_num +=1 → 无限打印1
运行后会一直打印1,停不下来,只能按Ctrl+C(Windows)或Command+C(macOS)停止。
▶ 避免无限循环的 3 个技巧
-
检查计数器更新:只要用了计数器(比如
current_num),必须在循环体里更新它(current_num +=1); -
打印关键变量:不确定循环是否会停时,打印计数器或条件变量,比如:
python
运行
current_num = 1 while current_num <= 5: print(f"当前current_num:{current_num}") # 打印计数器,确认是否更新 current_num +=1 -
设置最大循环次数:不确定条件时,加一个 “安全计数器”,超过次数就强制停止:
python
运行
current_num = 1 safe_count = 0 # 安全计数器 while current_num <= 5 and safe_count < 100: # 超过100次强制停止 print(current_num) current_num +=1 safe_count +=1
四、循环与列表结合:批量处理数据的实战场景
前面学了列表和循环,现在把它们结合起来 —— 这是 Python 中最常用的组合,能解决很多实际问题。咱们讲三个高频场景:
1. 场景 1:在列表之间移动元素
比如把 “待处理任务” 列表中的任务,逐个移到 “已处理任务” 列表:
python
运行
# 待处理任务列表
pending_tasks = ["写报告", "开会议", "回复邮件"]
# 已处理任务列表(空)
completed_tasks = []
# while循环:待处理列表不为空时,继续移动
while pending_tasks:
# 从待处理列表末尾取出一个任务(pop())
current_task = pending_tasks.pop()
print(f"正在处理:{current_task}")
# 把处理完的任务加入已处理列表
completed_tasks.append(current_task)
# 打印结果
print(f"\n待处理任务:{pending_tasks}") # 输出:待处理任务:[](空)
print(f"已处理任务:{completed_tasks}") # 输出:已处理任务:['回复邮件', '开会议', '写报告']
这里用pending_tasks作为while的条件 —— 列表为空时,pending_tasks为False,循环停止。
2. 场景 2:删除列表中所有特定值
比如删除水果列表中所有的 “苹果”(remove()只能删第一个,要删所有需要循环):
python
运行
# 原始水果列表(包含多个"苹果")
fruits = ["苹果", "香蕉", "苹果", "橙子", "苹果"]
# while循环:只要列表中有"苹果",就删除
while "苹果" in fruits:
fruits.remove("苹果") # 每次删第一个"苹果"
print(f"删除后的列表:{fruits}") # 输出:删除后的列表:['香蕉', '橙子']
为什么不用for循环?因为for循环遍历列表时,列表长度变化会导致漏删(比如删了第一个 “苹果” 后,后面的元素会前移,跳过下一个 “苹果”),while循环则会一直检查,直到没有 “苹果” 为止。
3. 场景 3:用循环生成复杂列表
比如生成 1~100 中所有能被 3 整除的数,并计算它们的总和:
python
运行
# 存储能被3整除的数
divisible_by_3 = []
total = 0
# for循环遍历1~100
for num in range(1, 101):
if num % 3 == 0: # 能被3整除(余数为0)
divisible_by_3.append(num)
total += num
print(f"1~100中能被3整除的数:{divisible_by_3}")
print(f"它们的总和:{total}") # 输出:它们的总和:1683
这个场景结合了for循环、range()、条件判断和列表操作,是典型的 “批量筛选 + 统计” 任务。
五、综合实操:学生成绩统计系统
咱们用今天学的循环知识,做一个 “学生成绩统计系统”,功能包括:
- 接收用户输入的 5 个学生成绩(用
while循环确保输入是有效数字); - 用
for循环遍历成绩列表,计算总分、平均分; - 找出最高分和最低分;
- 筛选出及格成绩(>60)并打印。
完整代码:
python
运行
# 学生成绩统计系统
print("===== 学生成绩统计系统 =====")
# 1. 输入5个学生成绩(确保输入是有效数字)
scores = []
count = 0 # 计数器:记录已输入的成绩个数
while count < 5:
# 接收用户输入
input_str = input(f"请输入第{count+1}个学生的成绩(0~100):")
# 检查输入是否为数字
if input_str.isdigit():
score = int(input_str) # 转换为整数
if 0 <= score <= 100: # 检查成绩是否在合理范围
scores.append(score)
count += 1 # 计数器更新
else:
print("成绩必须在0~100之间,请重新输入!")
else:
print("输入无效,请输入数字!")
# 2. 统计总分、平均分、最高分、最低分
total = 0
highest = scores[0] # 初始最高分设为第一个成绩
lowest = scores[0] # 初始最低分设为第一个成绩
for score in scores:
total += score # 计算总分
# 更新最高分
if score > highest:
highest = score
# 更新最低分
if score < lowest:
lowest = score
average = total / len(scores) # 计算平均分(len()获取列表长度)
# 3. 筛选及格成绩(>60)
passed = [score for score in scores if score > 60] # 列表推导式
# 4. 打印统计结果
print("\n===== 统计结果 =====")
print(f"输入的成绩:{scores}")
print(f"总分:{total}")
print(f"平均分:{average:.1f}") # 保留1位小数
print(f"最高分:{highest}")
print(f"最低分:{lowest}")
print(f"及格成绩:{passed}")
print("======================")
运行示例:
plaintext
===== 学生成绩统计系统 =====
请输入第1个学生的成绩(0~100):85
请输入第2个学生的成绩(0~100):abc
输入无效,请输入数字!
请输入第2个学生的成绩(0~100):105
成绩必须在0~100之间,请重新输入!
请输入第2个学生的成绩(0~100):72
请输入第3个学生的成绩(0~100):58
请输入第4个学生的成绩(0~100):93
请输入第5个学生的成绩(0~100):88
===== 统计结果 =====
输入的成绩:[85, 72, 58, 93, 88]
总分:396
平均分:79.2
最高分:93
最低分:58
及格成绩:[85, 72, 93, 88]
======================
这个系统用到了while循环处理用户输入、for循环统计数据、列表推导式筛选成绩,是对今天知识的综合应用,你可以跟着代码跑一遍,感受循环的强大。
六、小结与下一篇预告
这篇你学到了什么?
- for 循环:适合遍历列表、元组、字符串等序列,用
range()生成数值序列,用列表推导式高效生成列表; - while 循环:适合按条件重复执行,用计数器、标志位、
break/continue控制流程,避免无限循环; - 循环与列表结合:批量移动元素、删除特定值、筛选统计数据,解决实际问题;
- 避坑要点:注意循环缩进,更新计数器,打印关键变量排查问题。
下一篇预告
今天的循环能批量处理数据,但还不能 “根据不同情况做不同处理”—— 比如成绩 > 90 评 “优秀”,60~90 评 “及格”,这就需要条件判断(if 语句)。下一篇咱们会学if、if-else、if-elif-else结构,让循环处理数据时更智能,实现 “多分支逻辑”。
如果这篇内容帮你掌握了循环,欢迎在评论区分享你的 “成绩统计系统” 改进版本(比如添加 “按成绩降序排序” 功能),咱们一起交流进步~
- 点赞
- 收藏
- 关注作者
评论(0)