
看到标题里“程序控制语句”这几个字估计不少零基础的朋友脑子里冒出来的第一个念头是这玩意儿听着就抽象是不是又要背一堆语法我可以直接跟你说——程序控制语句恰恰是 Python 学习里最值得花时间的一块也是把“闷头执行”的代码变成“会动脑子”的代码的关键。简单说没有控制语句你的程序就是一条道走到黑从第一行执行到最后一行既不会根据情况做选择也不会反复干一件事。而控制语句就是给程序装上了红绿灯和复读机让代码能判断、能循环、能按条件走不同分支。这篇文章我会从零开始用尽量直白的方式把分支和循环讲透配上大量可以直接抄走的代码示例适合刚装好 Python 还不太清楚下一步学什么的朋友也适合想让基础更扎实的初学者。1. 先搭好脑回路认识程序的三种执行结构1.1 顺序执行程序默认的“流水线模式”几乎所有编程语言的程序默认都是一行一行往下跑的就像流水线上的工人做完第 1 道工序再做第 2 道不会跳着来也不会倒回去。Python 也一样这是最容易被新手忽略、却又最重要的前提。print(第一步打开冰箱门) print(第二步把大象放进去) print(第三步关上冰箱门)你运行这段代码输出的顺序一定是从上到下先“打开冰箱门”再“把大象放进去”最后“关上冰箱门”。如果你的需求永远是这么固定、不带任何变化那确实不需要控制语句。但真实场景里没有人会永远只做同一件事比如你写一个登录程序用户输入的密码有可能对、有可能错程序就必须根据不同的输入走不同的流程。这时候光靠顺序执行根本不够用于是就有了分支和循环两种结构。可以这么记顺序结构是程序的“默认跑道”分支是“岔路口”循环是“绕圈跑”。1.2 分支结构给代码装上“红绿灯”分支结构在代码里的表现就是if系语句。它的作用相当于给程序装了个红绿灯条件成立往左边这条路走条件不成立往右边那条路走。Python 里最基础的分支是if后面跟一个条件条件的结果只有两种——真True或假False。score 88 if score 60: print(恭喜及格了)这段代码很好理解如果成绩大于等于 60就输出“恭喜及格了”。问题来了——如果成绩是 58 呢那这个程序就什么都不输出。为了让“不及格”也有反馈我们需要加上else形成二选一。分支结构真正厉害的地方是可以嵌套多层的判断也可以连续判断多个条件这会在下一章详细展开。新手先把这个概念种进脑子里if就是程序做“选择”的方式有了选择代码才真正有了“智商”。1.3 循环结构让代码当“复读机”循环结构的价值更好理解代码里如果有某段逻辑需要重复执行几十次、几百次你不可能真的复制粘贴几百行而是要用循环让程序自动反复执行。Python 里最常见的两种循环是for和while后面会分别讲。打个比方你要给 50 个学生逐个登记成绩如果没有循环你就得手写 50 遍“请下一个同学”的逻辑。用循环只需要写一次程序会自己跑 50 遍。但循环有个前提必须注意你得让它知道什么时候停。尤其是while循环如果条件永远成立程序就会变成“死循环”一直在里面转圈像复读机卡住一样。这一点我会在第 4 章专门讲怎么避免因为几乎每个零基础学员都会踩一次这个坑。2. 分支控制实战if / elif / else 让代码学会“看情况办事”2.1 最简单的 if一个条件一条路先说一下if的最基本写法——完全是“傻瓜式”结构if 条件: 条件成立时要执行的代码需要注意两点第一条件后面有一个英文冒号第二条件成立时要执行的代码必须缩进通常是 4 个空格或一个 TabPython 就是靠缩进判断“哪些代码属于这个 if”的这一点和很多用花括号的语言不一样。我们写一个判断年龄是否成年的例子age 19 if age 18: print(成年了可以自己签名)如果age改成 15程序运行之后什么都不输出。你可能会觉得“什么都不输出”太安静了不友好那很正常——单分支本来就只处理“满足条件”这一种情况适合那些“不满足就什么都不用做”的场景比如“如果是 VIP 会员就打折”不是会员就不用操作。新手写的时候最容易忘掉冒号或者忘记缩进这俩都是运行时报错的重灾区别问我怎么知道的。2.2 if / else两条路二选一当你需要明确处理“满足”和“不满足”两种情况时用if / elsescore 58 if score 60: print(及格了继续加油) else: print(不及格需要补考)这个结构非常直观成绩大于等于 60走第一个分支否则走else分支。if / else有点像坐地铁时看指示屏“往左走是 1 号线往右走是 2 号线”不存在第三种选择。这里我想专门提醒一件事很多新手会把else后面也写上条件比如else score 60:这是错的。else本身代表“所有其他情况”它后面不能再跟条件直接跟冒号就行。如果写完if又想在中间加一层判断该用下一节讲的elif而不是else if。这个小区别看起来不起眼实际写代码时非常容易犯。2.3 if / elif / else多条件判断的正确姿势真实场景里条件往往不止两个。比如把百分制成绩分成“优、良、中、及格、不及格”五档这时候就需要elif——它是“else if”的缩写表示“否则再看下一个条件”。看代码score 82 if score 90: print(优秀) elif score 80: print(良好) elif score 70: print(中等) elif score 60: print(及格) else: print(不及格)这段代码的运行逻辑是先判断是否大于等于 90不是就看是否大于等于 80再不行就看 70、60最后落到else。注意elif可以有无数个但if只能有一个else最多也只能有一个而且else必须放在所有条件之后。我见过不少新手在这个地方会犯一个看似“聪明”的错——用多个独立的if代替elifif score 90: print(优秀) if score 80: print(良好) if score 70: print(中等)如果 score 是 95这段代码会同时输出“优秀”“良好”“中等”因为三个if条件都成立。用elif就不会有这个问题因为一旦第一个条件成立后面所有elif都不再判断。记住一句话判断同一件事的不同档次用elif判断互不相关的几件事才用多个if。2.4 布尔判断里的几个大坑写条件的本质是在算一个真假值也就是布尔值。这块虽然基础坑却不少我挑几个高频的讲。第一个坑是和分不清。是赋值才是判断相等。新手最容易把“判断 a 是否等于 b”写成if a b:这不是语义错误而是语法错误程序会直接报错。第二个坑是缩进范围if下面缩进的代码块默认包含所有连续缩进的行如果哪一行忘了缩进或者少缩进了一格程序要么报错要么那行就变成了和if无关的代码逻辑完全变了这类 bug 肉眼很难看穿一旦运行结果“匪夷所思”先检查缩进。第三个坑是条件的真假值。Python 里不只是True和False能表示真假任何非零数字、非空字符串、非空列表都是“真”0、空字符串、空列表是“假”。比如name if name: print(name 非空) else: print(name 是空的)这个特性善加利用会让代码很简洁比如判断用户有没有输入就可以直接写if user_input:不用写if len(user_input) 0:。但新手不理解时又会觉得“为什么 0 是假为什么空字符串是假”记住就好这是 Python 设计者的一个刻意选择。还有一点是关于多个条件的组合。Python 用and、or、not三个逻辑词而不是大多数人习惯的、||、!。写“18 到 60 岁之间”可以这样if age 18 and age 60: print(符合条件)甚至可以写成 Python 特有的链式比较if 18 age 60: print(符合条件)第二种写法很多其他语言不支持是 Python 的独门优势理解成本低代码也更像一句人话。3. 循环控制实战for 与 while 的性格完全不同3.1 for遍历一切可迭代对象for循环在 Python 里的地位非常高因为 Python 特别擅长处理各种“集合型”数据——列表、字符串、字典、元组这些都可以用for一个个取出来处理。for的直白翻译是“对每个元素做某事”看例子names [张三, 李四, 王五] for name in names: print(f欢迎 {name} 同学)for name in names的意思是依次把names里的每个元素取出来赋值给变量name然后执行缩进里的代码。第一次是“张三”第二次是“李四”第三次是“王五”结束。这个流程新手理解起来不难难的是自己写的时候不知道循环体里该放什么逻辑。另一种高频用法是用range()生成一个数字序列for i in range(1, 6): print(f第 {i} 次)range(1, 6)会生成从 1 到 5 的整数注意它不包含 6这是新手最容易踩的边界问题。如果你写range(1, 6)却以为会输出 6 个数搞定 1、2、3、4、5、6运行完发现少一个别慌不是程序坏了是 range 左闭右开。记住口诀range(开始, 结束) 包含开始不包含结束。想要 1 到 6 就让结束写成 7。另外如果只写一个参数比如range(5)就是从 0 数到 4。for循环特别适合用来做累加求和。比如求 1 加到 100total 0 for i in range(1, 101): total i print(total) # 结果是 5050这里total i是total total i的简写。循环 i 取到每一个数字就把它加进total里最后 total 变成了 5050。学到这里你可以试着自己写一个“计算 1 到 n 之间所有偶数之和”的小练习这是巩固for和range的经典题目。3.2 while条件成立就一直跑while和for最大的区别在于for天然知道要循环多少次取决于你遍历的对象有多长while不知道它只知道“只要条件为真就继续跑”。典型场景是“不断接收用户输入直到用户输入正确为止”。password while password ! 123456: password input(请输入密码) print(密码正确已进入系统)这段代码会一遍遍问用户要密码用户输入的是“123456”时循环条件password ! 123456变为 False循环结束。这个“直到满足条件才停”的模式正是while的主场。使用while时必须想清楚三件事初始值是什么、循环体做什么、什么时候让条件变成 False。拿上面例子来说password初始是空字符串循环体里用input让用户输入新值条件就是“不等于正确密码就继续”。新手学while最容易遇到的问题就是忘记让条件最终变成 False比如count 1 while count 5: print(count)你猜会发生什么count永远都是 1永远小于等于 5程序会不停打印 1直到内存撑不住。要让它正常结束必须在循环体里改变count的值count 1 while count 5: print(count) count 1 # 每次加 1总有一天会超过 5别看这只是一个count 1的差别几乎可以用“惨痛”来形容新手在死循环里挣扎的场景。我见过有学员拿笔记本写了一晚上的程序运行后卡死最后发现就是少了这一行。先记下这个教训写while先问自己循环体里有没有哪一行代码、在什么条件下能让循环条件变成 False。3.3 break 与 continue循环的“急刹车”和“跳过键”有了前面的基础我们再来看两个给循环“加特效”的语句break和continue。这两个从字面上就很好理解——break是“打破”直接终止整个循环continue是“继续”跳过当前这一轮进入下一轮。打个比方你在跑一场接力赛break就是裁判直接吹哨取消比赛全场结束continue是你这一棒没跑好裁判说“这棒不算下一棒重来”比赛继续。实际用处非常广。比如我们想找出 1 到 20 之间第一个能被 7 整除的数for i in range(1, 21): if i % 7 0: print(f第一个能被 7 整除的数是 {i}) break程序从 1 开始检查到 7 时条件成立打印结果后直接break后面的 14、21 都不会再看了。再比如只想输出 1 到 10 之间的偶数for i in range(1, 11): if i % 2 ! 0: continue print(i)i为奇数时就continue跳过后面的print直接进入下一轮循环。这两个语句在循环里组合使用非常灵活但也要注意别过度使用——如果你的逻辑到处是break和continue代码会变得像迷宫一样难读。一个好用的原则是能让循环条件自然结束的就不要用 break能不用 continue 化解的嵌套尽量先重构。3.4 嵌套循环九九乘法表从看懂到能默写循环里面套循环叫嵌套循环。它处理的是“乘法表”“打印图案”“遍历二维表格”这类需要双重循环的问题。先看完整代码for i in range(1, 10): for j in range(1, i 1): print(f{j} x {i} {i * j}, end\t) print()解释一下外层循环的i代表“第几行”从 1 到 9内层循环的j代表“这一行里要打印几个算式”range(1, i 1)保证了第 i 行正好有 i 个算式。end\t表示每次print之后不用换行而是用一个制表符分隔这样才能把同一行的算式排成一列每行内层循环结束后用一个空的print()换行。运行出来的结果大概是1 x 1 1 1 x 2 2 2 x 2 4 1 x 3 3 2 x 3 6 3 x 3 9新手在这一节最容易卡住的地方是为什么内层循环是range(1, i 1)不是range(1, 10)如果写死成 9每一行都会输出 9 个算式整个乘法表就成了一个完整的长方阵而我们要的是右上角被砍掉一半的三角形。这里的精髓就是让内层循环的次数依赖外层循环当前的i值——外层跑第 3 行内层就只从 1 跑到 3。理解这个“内外联动”的关系嵌套循环就算真正入门了。4. 新手的常见错误与调试心得4.1 缩进错误Python 的灵魂惩罚前面多次提到缩进因为它真的值得单独开一节。绝大多数编程语言用花括号{}划分代码块Python 不一样它用“缩进”表达“这段代码属于上一句”。这意味着你写的代码好不好看不再只是审美问题而是语法问题。常见错误有三种。第一种忘记冒号后面的代码块缩进系统直接报IndentationError: expected an indented block。第二种if内部的代码和if外部的代码缩进层级混在一起程序不报错但结果完全不对。第三种混用 Tab 和空格这是最阴间的错误——在屏幕上看起来缩进一致Python 却因为混用报TabError。个人建议是统一用 4 个空格不碰 Tab。几乎每个主流代码编辑器都会在右下角把“Tab 宽度”和“空格/制表符”显示出来新手先学会看这个栏能省掉一晚上的调试时间。4.2 高频报错速查表我在带零基础学员的过程中总结了几类出现频率最高的报错做成了一张速查表供你排查问题时对号入座。报错信息大概率原因一段出错示意SyntaxError: invalid syntax漏冒号、括号不匹配、关键字拼错if score 60少了冒号IndentationError: expected an indented blockif/for/while 下方没写缩进代码if score 60:下一行顶格写代码TabError: inconsistent use of tabsTab 和空格混用一半缩进是 Tab一半是空格NameError: name x is not defined变量没定义或拼写错误写scroe而不是scoreTypeError: int object is not iterable对不可迭代对象用了 forfor i in 10:ValueError: invalid literal for int()把非数字字符串转成整数int(abc)这张表不是让你背的而是提醒你遇到报错先别慌把报错信息从后往前读报错最后一行往往直接告诉你出问题的是哪一行。然后再对应上面的表格八成能在五分钟内定位问题。我见过太多新手一看到红字就心态爆炸其实很多报错就是漏冒号、少括号这种小事。4.3 无限循环程序卡死怎么办这一节专门讲死循环因为我敢打赌每一个学 Python 的人迟早都会遇到一次“程序怎么一直跑不停”。先说怎么处理已经发生的死循环。如果你在命令行或集成开发环境里运行代码时发现程序停不下来按Ctrl C强制终止这是最常用的“拔电源”操作。如果是 PyCharm 这类图形界面通常在运行窗口左边有一个红色方块按钮点它也能停止。先让程序停下来再回到代码里找问题。再来说怎么预防。死循环的根子基本只有三个while条件不会变成 False循环体里忘了更新变量条件本身写错导致永远为真。其中第一个最典型前面密码验证的例子只要把while password ! 123456:写成while True:却在循环体里没有break就死定了。还有一个非常隐蔽的死循环for循环里对正在遍历的列表做插入或删除操作导致列表长度一直在变循环怎么也走不到头。这种问题在实际业务代码里很常见新手先不用深究但要知道“循环过程中不要随便改正在遍历的容器”这条忠告。4.4 一个真实的排查案例统计班级成绩分布为了让上面的知识落地我模拟一个真实的调试场景。假设需要统计全班成绩把 85 分以上的人数和 60 分以下的人数分别统计出来。这是典型的分支加循环综合题很多新手第一次写出来是这样的scores [72, 88, 56, 91, 45, 83, 78, 64, 59, 92] high 0 low 0 for score in scores: if score 85: high 1 if score 60: low 1 print(f85 分以上 {high} 人60 分以下 {low} 人)这段代码是对的运行结果是“85 分以上 3 人60 分以下 3 人”没毛病。但如果有人多事把第二个if写成了if score 60: low 1在for循环外的同一缩进下会发生什么循环只会在所有遍历完成后执行一次if score 60此时score是最后一个元素 9292 不小于 60low就永远是 0。程序不报任何错结果却错得很安静。这种 bug 最可怕因为你不会收到报错提示只能靠肉眼仔细盯缩进。我给新手调试这类问题的建议很简单在关键位置用print打印中间结果比如在循环里先打印当前的score、high、low看一眼每一步的值对不对这样定位速度会比干瞪眼快十倍。5. 综合实战猜数字小游戏把控制语句一次性串起来5.1 需求拆解动笔写代码之前先“说人话”很多零基础学员有个习惯拿到一个小需求就开始敲代码结果敲到一半发现逻辑乱了。更靠谱的做法是先用“说人话”的方式把需求描述清楚再翻译成代码。以猜数字游戏为例需求可以拆成这几句话程序随机生成一个 1 到 100 之间的整数不要告诉用户。用户输入一个数字程序告诉用户“大了”或“小了”。用户继续猜直到猜对为止。猜对之后显示一共猜了多少次游戏结束。你会发现这几句话天然对应了今天的主题第一句和“顺序执行”有关第二到第四句几乎全是“选择”和“循环”——判断大小是if / elif反复猜是while猜对退出是break。把需求先“翻译”成人话再想办法用结构去实现这是后续进阶最重要的思维习惯。5.2 逐段代码讲解从导入库到收尾下面给出完整代码每一段我都会拆开解释。import random secret random.randint(1, 100) count 0 while True: guess input(请输入你猜的数字1-100) if not guess.isdigit(): print(输入无效请输入一个数字) continue guess int(guess) count 1 if guess secret: print(猜大了再试一次) elif guess secret: print(猜小了再试一次) else: print(f猜对啦答案就是 {secret}你一共猜了 {count} 次) break先看第一段import random是导入 Python 自带的随机数模块random.randint(1, 100)会返回一个 1 到 100 之间的随机整数。count 0是猜次数的计数器。接着是while True:这是一个无限循环意思是不管条件怎么样先跑起来。你可能会问这不是死循环吗没错它就是一个“有意为之”的死循环但我们用break在猜对的时候强行退出。这里就体现了break的价值——你不确定用户到底要猜几次只知道“猜对就停”用while True加break是最自然的写法。循环体里第一件事是input接收用户输入。注意input返回的一定是字符串所以接下来需要校验一下——guess.isdigit()会判断字符串是不是纯数字。不是纯数字就打印提示然后用continue跳回while True重新开始这一轮后面的代码一律不执行。这个前置校验非常重要否则用户输入一个“abc”int(abc)会直接抛 ValueError程序就崩了。通过校验后用int(guess)把字符串转成整数count 1记录次数。然后是经典的if / elif / else三段判断大于答案就提示“大了”小于答案就提示“小了”等于答案就打印祝贺信息用break结束整个循环。这段代码虽然短却完整覆盖了今天讲的顺序、分支、循环、break、continue、数据校验、计数器等几乎全部知识点。你能一行行看懂它控制语句就算真正入门了。我强烈建议你亲手把它敲一遍而不是复制粘贴——敲代码的动作本身就是在训练手指和大脑对语法的记忆。5.3 进阶改造3 个小改动让游戏更好玩基础版跑通之后可以试着做三个小改造每一个都对应一个新知识点。第一个改造限制猜的次数。给游戏增加一个“最多猜 5 次”的规则超过次数直接失败。实现思路是加一个max_try 5每次猜完后判断count max_try如果达到就打印失败信息并用break退出。这个练习能帮你在一个循环里同时控制两个退出条件。第二个改造把游戏改成单局可重玩。现在每次运行猜数字只能玩一局。你可以把整段逻辑放进一个函数里外面套一个while True玩完一局后问用户“是否再来一局”输入y就继续输入n就break。这会逼着你理清“循环嵌套”和“跳出哪一层”的关系值得试试。第三个改造改为“石头剪刀布”。程序随机出“石头”“剪刀”“布”用户输入对应文字程序判断胜负。这里虽然不用猜数字但判断胜负需要先列出所有情况——平局、玩家赢、玩家输——正好把if / elif / else的多条件判断再复习一遍。我的建议是先从猜数字开始跑通了再改规则一步一步来别一上来就挑战复杂的项目。6. 学完控制语句之后怎么走练习方向与我的实在话6.1 刻意练习清单从简单到综合看完文章不等于学会控制语句是那种“必须亲手写几十遍才有感觉”的知识点。我在这里留几个练习难度从低到高你可以每天做一个坚持一周判断一个数是奇数还是偶数输出对应提示。从 1 到 100 累加跳过所有 3 的倍数输出最终结果。打印一个由*组成的直角三角形行数由用户输入决定。输出 100 以内的所有素数。用循环实现斐波那契数列前 20 项输出。结合字符串操作实现一个简易登录系统账号密码均是固定值用户最多试 3 次。第六题基本把今天的知识点全串起来了做完之后你会明显感觉到自己写代码时的“卡壳感”少了很多。这些都是经典的初级编程题网上随便搜都能找到答案对照但我建议你先自己做实在做不出来再看答案然后用自己的话说一遍解题思路再隔一天重写一遍。6.2 上下游衔接列表推导式、异常处理别跳过控制语句学完后接下来该学什么我的建议是按这个顺序往下推先学列表和字典的常用操作再学函数的定义与调用然后学异常处理try / except最后学文件读写。这里面有一个知识点和你今天学的for关系极其密切就是列表推导式——它本质上是把for循环写进一行里从“取每个元素”到“加工每个元素并放到新列表”的简写。squares [x * x for x in range(1, 6)] print(squares) # [1, 4, 9, 16, 25]因为有了列表推导式很多以前需要写三四行for的代码现在一行就能完成这也是 Python 被说“优雅”的原因之一。等你玩转了列表推导式还可以进一步了解map / filter这类函数式风格工具再往后就可以去看专业的 Python 项目代码了。千万不要跳过异常处理前面的猜数字游戏里如果用户输入“abc”我们已经用isdigit挡掉了但更多场景里你无法预判所有输入try / except能帮你优雅地处理意外情况。它是控制语句最好的搭档也是从“入门”走向“能写真实程序”的必经路。6.3 我给零基础学员的两句实在话带我自己的学习经历和带学员的经验我想说两句特别重要的话。第一句是语法可以忘思路不能乱。刚学完一两天就把if怎么写忘掉太正常了忘了就去查但你要记住“程序里需要分情况讨论时就该用分支需要重复时就该用循环”这个思路思路在代码就永远写得出来。第二句是调试代码不是失败而是学习的一部分。我在给学生上课时经常故意把代码写错让他们看报错信息因为处理报错的能力几乎和写代码的能力同样重要。哪怕你写的代码第一次运行就报错只要你能读懂报错、定位问题、修好它这一次练习就已经值回票价了。有了一定的控制语句基础后你会开始觉得写代码“有点顺手”了——你不是在死记硬背而是真的让代码按你的意图去判断、去重复、去执行。这种感觉是学编程过程中最上瘾的阶段之一。希望这篇来自实战经验的文章能帮你顺利跨过这道门。写代码的路上踩坑是常态但你越早把分支和循环练熟后面的坑就越少。