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

举报
倔强的石头_ 发表于 2025/12/09 15:21:04 2025/12/09
【摘要】 本文介绍了Python中循环结构的核心概念和应用场景。重点讲解了for循环的基础用法(遍历列表、元组、字符串)和进阶用法(配合range()生成数值序列),并展示了高效的列表推导式写法。通过具体示例演示了如何用循环结构解决重复操作问题,如批量处理学生名单、统计字符出现次数、计算数值总和等。循环结构能大幅减少代码冗余,提高程序灵活性,是Python实现自动化的关键工具之一。

c6e3154d215982a75f2280a6ca6650b4.jpeg

文章目录


欢迎回到「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]}!")

这段代码能运行,但有两个大问题:

  1. 重复代码多:5 个学生要写 5 行 print,100 个学生就要写 100 行;
  2. 灵活性差:如果列表新增了学生,必须手动加一行 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

这里有两个关键点:

  1. 初始计数器:循环开始前要给计数器赋值(比如current_num=1);
  2. 更新计数器:循环体里必须更新计数器(比如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跳过,没有打印 ——continuebreak的区别是: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 个技巧

  1. 检查计数器更新:只要用了计数器(比如current_num),必须在循环体里更新它(current_num +=1);

  2. 打印关键变量:不确定循环是否会停时,打印计数器或条件变量,比如:

    python

    运行

    current_num = 1
    while current_num <= 5:
        print(f"当前current_num:{current_num}")  # 打印计数器,确认是否更新
        current_num +=1
    
  3. 设置最大循环次数:不确定条件时,加一个 “安全计数器”,超过次数就强制停止:

    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_tasksFalse,循环停止。

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()、条件判断和列表操作,是典型的 “批量筛选 + 统计” 任务。

五、综合实操:学生成绩统计系统

咱们用今天学的循环知识,做一个 “学生成绩统计系统”,功能包括:

  1. 接收用户输入的 5 个学生成绩(用while循环确保输入是有效数字);
  2. for循环遍历成绩列表,计算总分、平均分;
  3. 找出最高分和最低分;
  4. 筛选出及格成绩(>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循环统计数据、列表推导式筛选成绩,是对今天知识的综合应用,你可以跟着代码跑一遍,感受循环的强大。

六、小结与下一篇预告

这篇你学到了什么?

  1. for 循环:适合遍历列表、元组、字符串等序列,用range()生成数值序列,用列表推导式高效生成列表;
  2. while 循环:适合按条件重复执行,用计数器、标志位、break/continue控制流程,避免无限循环;
  3. 循环与列表结合:批量移动元素、删除特定值、筛选统计数据,解决实际问题;
  4. 避坑要点:注意循环缩进,更新计数器,打印关键变量排查问题。

下一篇预告

今天的循环能批量处理数据,但还不能 “根据不同情况做不同处理”—— 比如成绩 > 90 评 “优秀”,60~90 评 “及格”,这就需要条件判断(if 语句)。下一篇咱们会学ifif-elseif-elif-else结构,让循环处理数据时更智能,实现 “多分支逻辑”。

如果这篇内容帮你掌握了循环,欢迎在评论区分享你的 “成绩统计系统” 改进版本(比如添加 “按成绩降序排序” 功能),咱们一起交流进步~

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。