大家好,我是正在实战各种AI项目的程序员晚枫。
一个真实的故事 2023年,有个财务小姐姐找我求助:
"晚枫老师,我每个月要处理1000多个Excel文件,每个都要打开、复制数据、粘贴到汇总表...一天都做不完,有没有办法?"
我看了一眼,给了她一个脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import osimport pandas as pdall_data = [] for filename in os.listdir("文件夹路径" ): if filename.endswith(".xlsx" ): data = pd.read_excel(filename) all_data.append(data) result = pd.concat(all_data) result.to_excel("汇总.xlsx" , index=False ) print ("完成!共处理" , len (all_data), "个文件" )
原本一天的工作,变成了3秒钟。
这就是循环的力量——让程序自动重复做事,批量处理大量数据 。
上篇我们学了条件判断,程序能做选择了。这篇来学循环 ——让程序自动重复做事。
学完这篇,你就能批量处理100条、1000条、10000条数据,真正实现自动化办公。
为什么需要循环? 先看一个痛苦的需求:给100个人发欢迎消息。
不用循环(痛苦模式):
1 2 3 4 print ("欢迎张三!" )print ("欢迎李四!" )print ("欢迎王五!" )
用循环(优雅模式):
1 2 3 4 names = ["张三" , "李四" , "王五" , ...] for name in names: print (f"欢迎{name} !" )
一句话,循环帮你省了99%的重复代码。
循环的本质 循环就是让计算机帮你做重复的事:
1 2 人:做这件事100次 → 累死 计算机:做这件事100次 → 毫秒级完成
循环的应用场景:
批量处理文件(1000个Excel合并) 批量发送消息(100封邮件群发) 批量数据处理(爬取100页数据) 批量重命名(给500个文件加前缀) 批量下载(下载整个相册) for循环:遍历(一件一件地处理) for循环的工作方式,就像服务员依次接待排队的客人——来一个处理一个。
基本语法 1 2 3 4 fruits = ["苹果" , "香蕉" , "橙子" ] for fruit in fruits: print (f"我要吃:{fruit} " )
逐行解析:
1 2 3 fruits 的每个元素,依次取出,命名为 fruit 然后执行一次循环体(print那一行) 遍历完了,循环结束
运行结果:
for循环的执行流程 1 2 3 4 5 6 7 8 9 names = ["张三" , "李四" , "王五" ] for name in names: print (name)
遍历不同类型的数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 for char in "Python" : print (char) for num in [1 , 2 , 3 , 4 , 5 ]: print (num * 2 ) for item in (1 , 2 , 3 ): print (item) for fruit in {"苹果" , "香蕉" , "橙子" }: print (fruit) person = {"name" : "张三" , "age" : 25 } for key in person: print (key)
range函数:生成数字序列 如果想按顺序执行N次,用 range() 生成数字序列:
range的三种用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 for i in range (5 ): print (i) for i in range (2 , 6 ): print (i) for i in range (0 , 11 , 2 ): print (i) for i in range (5 , 0 , -1 ): print (i)
range的实际应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 for i in range (10 ): print ("Hello!" ) for i in range (1 , 101 ): print (i) fruits = ["苹果" , "香蕉" , "橙子" ] for i in range (len (fruits)): print (f"第{i+1 } 个水果:{fruits[i]} " ) for i in range (1 , 6 ): filename = f"报告_{i:03d} .txt" print (filename)
range的性能优势 1 2 3 4 5 6 7 8 9 r = range (1000000 ) print (r) for i in r: if i > 5 : break print (i)
while循环:条件满足就一直做 for 适合知道要循环多少次的情况。while 适合不知道要循环多少次,只要条件满足就一直做 的情况。
基本语法 1 2 3 4 5 count = 0 while count < 5 : print (count) count += 1
场景举例:猜数字游戏 你不知道对方要猜几次,只能一直猜,直到猜对为止:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import randomsecret = random.randint(1 , 100 ) guess = 0 attempts = 0 print ("猜数字游戏(1-100)" )while guess != secret: guess = int (input ("请输入你的猜测:" )) attempts += 1 if guess < secret: print ("太小了,再大一点" ) elif guess > secret: print ("太大了,再小一点" ) print (f"恭喜猜对了!答案就是{secret} ,你用了{attempts} 次" )
while的应用场景 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 while True : password = input ("请输入密码:" ) if password == "123456" : print ("密码正确!" ) break print ("密码错误,请重试" ) data = [] while True : line = input ("请输入数据(输入q结束):" ) if line == 'q' : break data.append(line) max_retries = 3 retry_count = 0 while retry_count < max_retries: success = send_email() if success: print ("发送成功!" ) break retry_count += 1 print (f"发送失败,重试第{retry_count} 次..." ) if retry_count == max_retries: print ("发送失败,请稍后重试" )
while的陷阱:无限循环 1 2 3 4 5 6 7 8 9 10 11 12 13 count = 0 while count < 5 : print (count) count = 0 while count < 5 : print (count) count += 1
循环控制:break 和 continue break:中途退出 遇到某个条件就不做了,直接跳出整个循环:
1 2 3 4 5 6 7 8 9 10 numbers = [1 , 3 , 5 , -2 , 7 , 9 ] for num in numbers: if num < 0 : print (f"发现负数:{num} " ) break print (f"处理:{num} " ) print ("循环结束" )
运行结果:
1 2 3 4 5 处理:1 处理:3 处理:5 发现负数:-2 循环结束
continue:跳过这次 遇到某个条件跳过这一次,继续下一个:
1 2 3 4 5 for i in range (10 ): if i % 2 == 0 : continue print (i)
运行结果:
break vs continue 1 2 3 4 5 6 7 8 9 10 11 12 13 for i in range (5 ): if i == 3 : break print (i) for i in range (5 ): if i == 3 : continue print (i)
实际应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 while True : age = input ("请输入年龄:" ) if not age.isdigit(): print ("请输入数字!" ) continue age = int (age) if age < 0 or age > 150 : print ("年龄不合理,请重新输入" ) continue print (f"你的年龄是{age} 岁" ) break students = [ {"name" : "张三" , "score" : 85 }, {"name" : "李四" , "score" : 92 }, {"name" : "王五" , "score" : 78 } ] target = "李四" for student in students: if student["name" ] == target: print (f"找到{target} ,分数:{student['score' ]} " ) break else : print (f"没找到{target} " )
for-else和while-else Python特有的语法:循环正常结束(没有break)时执行else:
1 2 3 4 5 6 7 8 for n in range (2 , 10 ): for x in range (2 , n): if n % x == 0 : print (f"{n} = {x} × {n//x} " ) break else : print (f"{n} 是质数" )
运行结果:
1 2 3 4 5 6 7 8 2 是质数 3 是质数 4 = 2 × 2 5 是质数 6 = 2 × 3 7 是质数 8 = 2 × 4 9 = 3 × 3
注意: else在循环正常结束时执行,如果break退出了,else不会执行。
遍历字典:键、值、键值对 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 person = {"姓名" : "张三" , "年龄" : 25 , "城市" : "北京" } for key in person: print (key) for key in person.keys(): print (key) for value in person.values(): print (value) for key, value in person.items(): print (f"{key} :{value} " )
嵌套字典的遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 students = { "张三" : {"语文" : 85 , "数学" : 92 , "英语" : 78 }, "李四" : {"语文" : 90 , "数学" : 88 , "英语" : 95 }, "王五" : {"语文" : 75 , "数学" : 85 , "英语" : 82 } } for name, scores in students.items(): print (f"\n{name} 的成绩:" ) for subject, score in scores.items(): print (f" {subject} :{score} " ) avg = sum (scores.values()) / len (scores) print (f" 平均分:{avg:.1 f} " )
同时遍历多个序列:zip 基本用法 1 2 3 4 5 names = ["张三" , "李四" , "王五" ] ages = [25 , 30 , 28 ] for name, age in zip (names, ages): print (f"{name} ,{age} 岁" )
运行结果:
zip的特性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 list1 = [1 , 2 , 3 , 4 , 5 ] list2 = ['a' , 'b' , 'c' ] for num, char in zip (list1, list2): print (num, char) names = ["张三" , "李四" , "王五" ] ages = [25 , 30 , 28 ] cities = ["北京" , "上海" , "广州" ] for name, age, city in zip (names, ages, cities): print (f"{name} ,{age} 岁,来自{city} " )
创建字典 1 2 3 4 5 6 keys = ['name' , 'age' , 'city' ] values = ['张三' , 25 , '北京' ] person = dict (zip (keys, values)) print (person)
enumerate:获取索引和值 1 2 3 4 5 6 7 8 9 10 11 12 13 fruits = ["苹果" , "香蕉" , "橙子" ] for i in range (len (fruits)): print (f"{i} :{fruits[i]} " ) for index, fruit in enumerate (fruits): print (f"{index} :{fruit} " ) for index, fruit in enumerate (fruits, start=1 ): print (f"第{index} 个:{fruit} " )
运行结果:
嵌套循环:循环里的循环 九九乘法表 1 2 3 4 for i in range (1 , 10 ): for j in range (1 , i + 1 ): print (f"{j} ×{i} ={i*j} " , end="\t" ) print ()
运行结果:
1 2 3 4 5 6 1×1=1 1×2=2 2×2=4 1×3=3 2×3=6 3×3=9 1×4=4 2×4=8 3×4=12 4×4=16 1×5=5 2×5=10 3×5=15 4×5=20 5×5=25 ...
遍历嵌套结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 matrix = [ [1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ] ] for row in matrix: for item in row: print (item, end=" " ) print () target = 5 found = False for i, row in enumerate (matrix): for j, item in enumerate (row): if item == target: print (f"找到{target} ,位置:第{i} 行第{j} 列" ) found = True break if found: break
打印各种图案 1 2 3 4 5 6 7 8 9 10 11 12 13 14 for i in range (1 , 6 ): print ("*" * i) for i in range (5 , 0 , -1 ): print ("*" * i) n = 5 for i in range (1 , n + 1 ): spaces = " " * (n - i) stars = "*" * (2 * i - 1 ) print (spaces + stars)
列表推导式:一行写循环 Python特有的简洁写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 squares = [] for i in range (10 ): squares.append(i ** 2 ) squares = [i ** 2 for i in range (10 )] evens = [i for i in range (20 ) if i % 2 == 0 ] matrix = [[i * j for j in range (1 , 4 )] for i in range (1 , 4 )]
字典推导式 1 2 3 4 5 6 7 8 squares = {i: i**2 for i in range (5 )} original = {'a' : 1 , 'b' : 2 , 'c' : 3 } swapped = {v: k for k, v in original.items()}
避坑指南 ❌ 坑1:忘记更新循环变量(while) 1 2 3 4 5 6 7 8 9 10 count = 0 while count < 5 : print (count) count = 0 while count < 5 : print (count) count += 1
❌ 坑2:在循环中修改正在遍历的列表 1 2 3 4 5 6 7 8 9 10 11 12 13 numbers = [1 , 2 , 3 , 4 , 5 ] for num in numbers: if num % 2 == 0 : numbers.remove(num) numbers = [num for num in numbers if num % 2 != 0 ] for num in numbers[:]: if num % 2 == 0 : numbers.remove(num)
❌ 坑3:range的边界 1 2 3 4 5 6 7 for i in range (5 ): print (i) for i in range (1 , 6 ): print (i)
❌ 坑4:无限循环无法退出 1 2 3 4 5 6 7 8 9 10 while True : user_input = input ("输入q退出:" ) while True : user_input = input ("输入q退出:" ) if user_input == 'q' : break
❌ 坑5:浮点数循环 1 2 3 4 5 6 7 8 9 10 11 i = 0 while i != 1 : i += 0.1 i = 0 while i < 10 : i += 1 x = i / 10
性能对比:不同的循环方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import timedef method1 (): result = [] for i in range (10000 ): result.append(i ** 2 ) return result def method2 (): return [i ** 2 for i in range (10000 )] def method3 (): return list (map (lambda x: x ** 2 , range (10000 ))) start = time.time() method1() print (f"普通for循环: {time.time() - start:.4 f} 秒" )start = time.time() method2() print (f"列表推导式: {time.time() - start:.4 f} 秒" )start = time.time() method3() print (f"map函数: {time.time() - start:.4 f} 秒" )
结论: 列表推导式通常最快,也最易读。
实战练习:批量重命名文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import osfrom datetime import datetimedef batch_rename (folder, prefix=None , suffix=None ): """批量重命名文件""" if not os.path.exists(folder): print ("文件夹不存在" ) return files = [f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))] count = 0 print (f"找到 {len (files)} 个文件" ) print ("-" * 40 ) for i, filename in enumerate (files, 1 ): name, ext = os.path.splitext(filename) parts = [] if prefix: parts.append(prefix) parts.append(name) if suffix: parts.append(suffix) new_name = "_" .join(parts) + ext new_path = os.path.join(folder, new_name) old_path = os.path.join(folder, filename) os.rename(old_path, new_path) count += 1 print (f"{i} . {filename} → {new_name} " ) print ("-" * 40 ) print (f"✅ 完成,共处理 {count} 个文件" )
实战练习:批量处理Excel 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import pandas as pdimport osdef merge_excel_files (folder, output_file="汇总.xlsx" ): """合并文件夹中的所有Excel文件""" all_data = [] for filename in os.listdir(folder): if filename.endswith(('.xlsx' , '.xls' )): filepath = os.path.join(folder, filename) try : df = pd.read_excel(filepath) df['来源文件' ] = filename all_data.append(df) print (f"✓ 已读取:{filename} ({len (df)} 行)" ) except Exception as e: print (f"✗ 读取失败:{filename} ,错误:{e} " ) if not all_data: print ("没有找到Excel文件" ) return result = pd.concat(all_data, ignore_index=True ) result.to_excel(output_file, index=False ) print ("-" * 40 ) print (f"✅ 合并完成!共 {len (result)} 行数据" ) print (f"📄 保存到:{output_file} " )
实战练习:进度条效果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import timedef progress_bar (total, task_name="处理中" ): """显示进度条""" for i in range (total + 1 ): percent = i / total * 100 bar_length = int (percent / 2 ) bar = '█' * bar_length + '░' * (50 - bar_length) print (f'\r{task_name} : [{bar} ] {percent:.1 f} %' , end='' ) time.sleep(0.05 ) print () progress_bar(100 , "下载文件" )
📚 推荐:Python 零基础实战营 系统学习Python,推荐这个免费入门课程 👇
特点 说明 🎯 专为0基础设计 门槛低,上手快 📹 配套视频讲解 配合文章学习效果更好 💬 专属答疑群 遇到问题有人带 🎁 实体书赠送 优秀学员送《Python编程从入门到实践》
👉 点击免费领取 Python 零基础实战营
本讲小结 概念 说明 for item in 列表:依次取出每个元素来处理 range(n)生成 0 到 n-1 的数字序列 while 条件:条件满足就一直做 break退出整个循环 continue跳过本次,进入下一次 .items()同时遍历字典的键和值 zip(a, b)同时遍历两个列表 enumerate()获取索引和值 列表推导式 [x for x in 列表 if 条件]
下节预告 掌握了循环,下一篇来学函数 ——把一段代码打包成一个工具,想用就用,让代码复用更方便。
你将学会:
函数的定义和调用 参数和返回值 默认参数和关键字参数 变量作用域 递归函数 👉 继续阅读:Python函数基础
课程导航 上一篇: Python条件判断-if-else完全指南
下一篇: Python函数基础-从定义到调用
相关阅读 PS:循环是自动化的核心——搞定了循环,你就搞定了批量处理。生活中有什么重复性的事,试试用循环来实现吧!记住:程序员最讨厌的事就是重复做同样的事,所以我们发明了循环。
2026-04-23 更新 by 程序员晚枫
🎓 AI 编程实战课程 想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!