Python判断与循环语句:构建程序逻辑的核心

发布时间:2026/10/12 13:26:07
Python判断与循环语句:构建程序逻辑的核心
day03_判断语句与循环语句1. 这一关到底在学什么如果你正在自学编程翻开任何一本入门教材基本都会在很靠前的位置碰到判断语句和循环语句。很多初学者容易产生一个误解觉得既然已经学会了变量、数据类型、运算符为什么还要专门花一整天去啃这两个看起来不起眼的东西我的看法是如果把前面的内容比作认识了砖头、水泥和钢筋那判断语句和循环语句就是第一次开始真正搭建结构。它们决定了程序能不能“思考”、能不能“重复干活”这是从写几行玩具代码过渡到解决实际问题的第一道分水岭。以 Python 为例判断语句的核心是if、elif、else循环语句的核心是for和while。语法本身掰着指头数都能数过来难的是两件事第一理解程序执行时的走向是怎么被这些语句改变的第二在实际需求里知道该用哪个怎么组合不出错。整篇文章我会按“先理解为什么再讲怎么用最后放实战和排坑”的顺序来写适合刚学完变量和基础运算符、准备开始接触流程控制的初学者参考也适合教别人入门时当作备课思路。我见过不少朋友在这个阶段学得很痛苦不是因为语法记不住而是因为脑子里没有一个清晰的模型程序是怎么从一个条件判断跳到另一个条件的循环到底是在什么时候退出的如果你也有这种困惑我建议你在读这篇文章的时候旁边放一张纸每遇到一个例子就手动把执行流程画一遍。这是我在带新人时反复强调的做法效果比盯着屏幕看十遍都好。2. 判断语句给程序装上“岔路口”2.1 为什么需要判断语句先想一个最简单的场景你写了一个程序要求用户输入一个数字如果这个数字大于零就打印“正数”。如果没有判断语句你只能让程序把输入原样打印出来或者做统一的运算但无法根据输入的不同做出不同的响应。这种“根据某种条件选择不同路径”的能力就是判断语句存在的意义。生活中到处都是这样的决策过程出门前看天气下雨就带伞不下雨就不带网购时看价格超过预算就放弃没超过就下单。把这些场景翻译成代码就是if 条件成立: 执行某件事。Python 的判断语句写法非常接近自然语言age 18 if age 18: print(可以办理)这里的age 18是一个布尔表达式它的结果只有两种可能——True或者False。当结果为True时缩进的代码块会被执行如果是FalsePython 会跳过这段代码继续往下走。提示if后面那一行的缩进必须一致通常用 4 个空格。Python 靠缩进来识别代码块跟很多其他语言用花括号的方式不一样。初学者常犯的毛病是混用空格和 Tab看起来缩进没问题运行时直接报错。2.2if、elif、else的完整组合实际需求很少只有两种情况更多的是多分支判断。比如根据成绩分数给出等级90 分以上是优秀80 到 90 是良好60 到 80 是及格60 以下是需要努力。这种场景用单个if显然不够需要多个分支协同工作。score 85 if score 90: grade 优秀 elif score 80: grade 良好 elif score 60: grade 及格 else: grade 需要努力 print(grade)这里面有几个特别重要的细节初学阶段很容易忽略第一elif是“否则如果”的意思它必须跟在if或者另一个elif后面不能单独使用。程序从上往下依次判断一旦某个条件成立后面的elif和else就全部不再执行。所以上面这个例子中当score 85时第一个条件score 90不满足继续检查第二个条件score 80成立执行grade 良好然后直接跳出整个判断结构后面的elif和else都被跳过。第二条件的顺序很重要。如果把elif score 60放到elif score 80前面那么 85 分会被判成“及格”因为85 60成立了程序根本不会继续检查后面的条件。我见过很多人踩这个坑写出的代码逻辑上完全错了但语法没有报错特别难排查。记住一个原则多个互斥条件放在if/elif链里时应该先写范围更窄、更具体的条件再写范围更宽的条件。第三else可以省略。如果不需要处理“其他所有情况”就不必写它。但反过来只要写了else就表示“前面所有条件都不满足时执行这里”它不需要任何条件表达式。2.3 嵌套判断与布尔运算的配合有时候条件不是单层的。比如判断一个年份是否为闰年规则是能被 4 整除但不能被 100 整除或者能被 400 整除。这个规则本身就带着逻辑运算符用and和or可以直接表达year 2024 if (year % 4 0 and year % 100 ! 0) or (year % 400 0): print(f{year} 是闰年) else: print(f{year} 不是闰年)这段代码展示了两个知识点一是逻辑运算符and、or的优先级问题建议在复杂条件里主动加括号不要依赖记忆去判断优先级二是判断语句里的条件表达式也可以是复合布尔表达式判断语句在意的是最终结果是True还是False。嵌套判断指的是在一个判断代码块内部再写一层判断。比如登录功能里先判断用户名是否存在再判断密码是否正确这就是典型的嵌套username admin password 123456 if username admin: if password 123456: print(登录成功) else: print(密码错误) else: print(用户名不存在)嵌套不是不能用但嵌套层数越多代码读起来越累。一般超过两层我就会考虑能不能把条件拆开用逻辑运算符合并成单层判断或者提前把不满足条件的情况用return或exit切掉减少嵌套深度。这也是一个代码风格问题后面我还会再提。2.4 条件表达式一行搞定简单判断Python 提供了一种简写形式叫做条件表达式也常被称为三元表达式。它的结构是值1 if 条件 else 值2当条件成立时整个表达式的值是值1不成立时是值2。比如判断一个数是奇数还是偶数num 7 result 奇数 if num % 2 0 else 偶数我平时会在“根据条件给变量赋不同值”这种简单场景下用它赋值语句写一行就结束非常清爽。但我不建议在三元表达式里继续嵌套三元表达式比如值1 if 条件1 else (值2 if 条件2 else 值3)这种写法虽然语法上合法可读性却会直线下降别人维护你的代码时会非常痛苦。简单逻辑用三元表达式复杂逻辑老老实实写if/elif/else这是我个人的准则。2.5 Python 的真值判断细节初学if时大家习惯性地把条件写成比较表达式比如if x 0。但 Python 里有个非常实用又容易被忽略的特性任意对象都可以直接放在if后面作为条件Python 会隐式地把它转换成布尔值。name if name: print(name 不为空) else: print(name 是空的) items [1, 2, 3] if items: print(列表有元素)这里的规则是空字符串、空列表、空字典、空集合、数字 0、None这些都是假值会被当成False来处理其余大多数对象都是真值会被当成True。这个特性写起来很方便但有一个潜在风险新手容易误以为if name是在判断“name 是否等于空字符串”实际上它判断的是“name 转换后的布尔值是否为 True”。大多数时候结果是一致的但如果你定义了一个自定义类它的__bool__或__len__方法行为很特殊这个隐式转换可能会带来意外。入门阶段不需要深究这些但至少要知道有这回事。3. 循环语句让代码学会“重复劳动”3.1for循环与range()如果说判断语句是岔路口那循环语句就是传送带。程序需要反复执行某段代码比如打印 1 到 100 的数字不可能手动写一百行print这时候就该循环出场了。Python 的for循环和 C 语言风格的for循环不太一样。它更适合理解为“遍历序列中的每一个元素”。序列可以是列表、字符串、元组、字典的键甚至是range()生成的一段整数序列。for i in [1, 2, 3]: print(i) for char in hello: print(char)range()是for循环最常用的搭档。它有几种用法range(n)生成从 0 到 n-1 的整数range(start, stop)生成从 start 到 stop-1 的整数range(start, stop, step)按 step 步长生成for i in range(5): print(i) # 0 1 2 3 4 for i in range(2, 8): print(i) # 2 3 4 5 6 7 for i in range(1, 10, 2): print(i) # 1 3 5 7 9注意range的结束值是不包含的。很多人刚学时会把范围当成数学里的闭区间写range(1, 10)以为会包含 10结果打印到 9 就停了。其实这是 Python 里一个统一的设计惯例切片、range都遵循左闭右开原则。用惯了之后你会觉得这样很顺手因为它天然能表达“取前 n 个元素”这类需求。3.2while循环与循环条件while循环的结构是只要条件为真就一直执行循环体。它和for循环的区别在于for适合“我知道要遍历几次”的场景while适合“我不知道具体次数只知道什么时候该停”的场景。比如猜数字游戏用户可以反复猜直到猜中为止。猜了多少次事先是不确定的这就是while的典型应用场景。secret 42 guess 0 while guess ! secret: guess int(input(请输入你猜的数字)) if guess secret: print(猜小了) elif guess secret: print(猜大了) print(恭喜猜对了)写while循环最核心的一个注意点是必须保证循环过程中条件有变成False的可能也就是说要有某种方式让循环退出否则就是死循环。上面这个例子里如果用户一直猜错程序会一直运行下去看起来就像卡死了实际上是在等待新的输入。这种“卡死”的状态很多初学者会误以为是程序崩溃了。区分的方法是看终端里有没有继续输出提示、光标是不是还在等待输入。如果完全卡住没有任何输出那大概率是进入了死循环。# 常见死循环示例忘了在循环体里更新条件变量 count 0 while count 10: print(count) # 少了 count 1这段代码会一直打印 0因为count的值从未改变条件count 10永远成立。3.3break、continue和else循环语句有两个非常实用的控制指令break和continue。break的作用是立刻终止当前循环不再执行循环体里break之后的任何代码也不再进入下一轮循环。它通常和if搭配使用用来“提前退出”。for i in range(100): if i 10: break print(i) # 打印 0 到 9到 10 时循环结束continue的作用是跳过当前这一轮循环中剩下的代码直接进入下一轮循环。for i in range(10): if i % 2 0: continue print(i) # 打印 1 3 5 7 9跳过偶数用生活化的类比break是你在排队时突然决定不排了直接离开队伍continue是轮到你时发现自己没带材料先跳过这一轮重新排队等着下一轮。还有一个容易被忽略的知识点for或while循环后面可以跟else子句。它的执行时机是循环正常结束时执行else块如果循环是因为break跳出的则else块不会执行。for n in range(2, 10): for x in range(2, n): if n % x 0: break else: print(n, 是质数)这段经典代码利用循环else的特性来判断质数内层循环如果找到了能整除 n 的数就break跳过如果内层循环完整遍历完都没有找到说明 n 是质数这时执行else块。这个写法比用标志变量判断简洁很多建议好好体会一下。3.4 嵌套循环与执行顺序循环里面再放循环就叫嵌套循环。最经典的例子是打印九九乘法表for i in range(1, 10): for j in range(1, i 1): print(f{j} * {i} {i * j}\t, end) print()执行顺序是外层循环先取 i1然后完整执行一遍内层循环j 从 1 到 1内层结束后换行然后外层循环取 i2再完整执行内层循环j 从 1 到 2以此类推。嵌套循环的时间复杂度是内外层次数的乘积这点在写代码时一定要有意识。如果外层循环 1000 次内层循环 1000 次总共就是 100 万次操作。当然对入门案例来说不是问题但到了写真实项目时嵌套层数和每次循环里的操作都要仔细评估不然性能会很差。我见过一个新手写的代码里层循环里放了一个非常耗时的数据库查询外层循环 500 次结果程序跑了半个多小时都没结束。优化思路很多比如提前把数据一次性查出来缓存到内存里把嵌套里的查询移出来等等。这说明学习循环时不能只满足于语法还要有性能意识。3.5 循环里的陷阱range的惰性特性在 Python 2 里range()会直接生成一个真正的列表如果范围很大内存占用非常可观。Python 3 做了改进range()返回的是一个可迭代对象它并不一次性生成所有数字而是按需产生下一个数字。这意味着range(1000000000)并不会立刻在内存里创建一个包含十亿个元素的列表这对内存非常友好。与之类似的一个概念是生成器。如果你在循环里需要遍历非常大的数据集合可以考虑用生成器表达式或者yield来按需产生值。入门阶段不必深入但知道这一点能避免踩到“内存暴涨”的坑。4. 从语法到实战几个必练小项目4.1 猜数字小游戏综合运用循环与判断我强烈建议每个初学者在学完判断和循环后亲手写一个猜数字游戏。这个项目麻雀虽小五脏俱全涵盖了随机数生成、while循环、if/elif/else判断、break退出条件、用户输入处理等关键知识点。import random target random.randint(1, 100) count 0 while True: try: guess int(input(请输入 1-100 之间的整数)) except ValueError: print(输入的不是有效数字请重新输入) continue count 1 if guess target: print(猜小了) elif guess target: print(猜大了) else: print(f猜对了一共猜了 {count} 次) break这个代码里有两个值得注意的地方。第一while True是一个“永远为真”的循环所以循环体内必须有break来终止它否则就死循环了。第二处理用户输入的时候用了try/except来捕获ValueError防止用户输入非数字导致程序崩溃。这个习惯在真实项目中非常重要用户的行为永远不可预测。写完基本版本之后我建议你自己扩展几个功能限制最多猜的次数、猜完一个数字后询问是否继续玩、加一个计分功能。这些扩展会逼着你把判断和循环结合起来用比单独背语法有用得多。4.2 计算器里的菜单循环处理“退出”逻辑另一个很好的练习是写一个带菜单的计算器。用户输入 1 执行加法、输入 2 执行减法、输入 3 退出。核心是“菜单要一直显示直到用户选择退出”这天然就是while循环的场景。while True: print(1. 加法) print(2. 减法) print(3. 退出) choice input(请选择功能) if choice 1: a float(input(请输入第一个数)) b float(input(请输入第二个数)) print(f结果是{a b}) elif choice 2: a float(input(请输入第一个数)) b float(input(请输入第二个数)) print(f结果是{a - b}) elif choice 3: print(再见) break else: print(无效选择请重新输入)这个例子里展示了一个常见的交互模型不断读取输入、执行操作、回到菜单。真实项目里的命令行工具、游戏主循环等都是类似的套路。把这段练熟你会对“事件循环”这个概念有初步的感知。4.3 累加求和与计数循环的入门用法如果你觉得上面两个项目还有点复杂可以先从简单的累加开始。计算 1 到 100 的和、统计列表里的偶数个数、找到一组数里的最大值这些基础的求和与计数问题能帮你建立循环的执行思维。用for累加求和total 0 for i in range(1, 101): total i print(total) # 5050用while做同样的事total 0 i 1 while i 100: total i i 1 print(total)用continue跳过不需要的值total 0 for i in range(1, 101): if i % 2 1: continue total i print(total) # 246...100这些题目看上去简单但我建议你不要只是看懂而是真的动手敲一遍然后变着花样改条件。它会让你对循环体里每一行代码的执行次数有直觉。5. 常见报错与调试技巧5.1 缩进错误这是初学阶段遇到的最多报错之一。如果缩进不一致Python 会抛出IndentationError或者TabError。解决方法很简单统一使用 4 个空格编辑器里把 Tab 键自动转换成空格。注意很多现代编辑器默认会把 Tab 转成空格但如果你在多个编辑器之间切换或者复制别人的代码很容易混入真正的制表符。可以在编辑器设置里开启“显示空白字符”功能直接在视觉上分辨空格和 Tab。5.2 无限循环特征程序运行时一直没有输出或者输出内容重复且无法停止。排查方法检查while循环的条件是否有可能变成False检查循环体里是否忘了更新条件变量检查是否用了while True但漏写了break。5.3 条件判断总是进入同一个分支这种情况很隐蔽因为语法完全正确只是逻辑错了。常见原因有两种一是条件顺序不对范围大的条件放在了前面拦截了后面更具体的条件二是比较运算符用混了比如把赋值当成了比较。Python 里把赋值写在if条件里会直接报语法错误所以这类问题主要出在条件设计上。遇到这种问题时我的调试习惯是在每个分支的开头加一行print打印当前进入的分支和当时变量的值。比如if score 60: print(进入及格分支score , score)通过查看这些输出就能很快定位是哪一步的逻辑不符合预期。这个技巧很简单但非常有效。5.4 调试工具与断点法除了print大法Python 自带的调试器pdb也很值得学习。你可以在代码里加入一行import pdb; pdb.set_trace()程序运行到这一行时会暂停进入交互式调试模式可以查看变量值、单步执行。不过对入门阶段来说我建议先养成用 print 观察执行流的好习惯。它直观、不需要额外学习成本等碰到 print 解决不了的复杂问题再引入调试器也不迟。另一个非常实用的调试技巧是“注释法”把代码中的某些部分注释掉缩小问题范围。比如怀疑问题出在循环里的某个计算上就先注释掉print语句只保留计算观察变量怎么变化。5.5 常见问题速查表问题现象可能原因排查方向IndentationError缩进不一致混用 Tab 和空格显示空白字符统一为 4 空格SyntaxError在 if 行if后面缺少冒号检查是否写成if x 0而漏了:程序不进入任何分支所有条件都为False且没有else检查条件表达式和变量值程序只执行第一个分支条件顺序不当宽条件拦截了窄条件调整条件顺序先窄后宽死循环无法停止循环条件一直为真或缺少 break检查循环体更新语句和退出分支打印结果包含最后一项的“下一项”range 结束值不包含检查左闭右开规则6. 我的一点学习体会判断语句和循环语句是整个编程学习里少有的“必须亲手练够量才能内化”的知识点。语法可以看一遍就懂但手感必须通过大量练习才能建立。我碰到过一位初学者他把if和for的语法倒背如流但让他写一个“从 1 数到 100 打印偶数”的程序他想了半天不知道从哪里下手。这说明知识在大脑里还没建立执行模型。我给的解决办法很简单让他把纸笔拿出来画出程序每一步的执行轨迹。画过几次之后这类问题自然就消失了。归根结底判断语句是在回答“现在该走哪条路”循环语句是在回答“这件事要重复多少次”。把它们组合起来程序才算有了最基础的主干。这一关的内容虽然基础却决定了你后续学函数、数据结构时能不能顺畅理解。我建议你学完这一章之后至少完成猜数字游戏的迭代版本并试着把它扩展成带计分和难度选择的工具相信我做完之后你会发现自己对流程控制的理解已经上了一个台阶。