Python 循环与条件判断
在 Python 编程中,循环语句 和条件语句是控制程序流程的基石。它们决定了代码何时执行、何时停止以及执行哪一部分。
循环语句
Python 提供了两种主要的循环方式:for 循环用于遍历集合,while 循环用于满足条件时的持续执行。
1. for 循环
for 循环通过迭代器遍历列表等可迭代对象。需要注意的是与其他语言不同,Python 使用缩进来定义代码块(作用域),而不是大括号。
基础语法与缩进规则:
- 必须缩进:循环体内的代码必须有缩进(空格或制表符),否则会报错。
- 冒号结尾 :
for语句结尾必须加:。 - 变量作用域(泄露效应) :在
for循环中定义的变量,在循环结束后依然可以使用。它不会被销毁,而是保留最后一次迭代的值。 - 循环体不能为空 :与其他编程语言不同,Python 的循环体内必须有具体的操作代码 。如果暂时不想写操作,不能留空,否则会报错(可以使用
pass语句占位)。
python
magicians = ['alice', 'david', 'carolina']
# 正确的缩进
for magician in magicians:
print(magician)
# 循环结束后,变量 magician 依然可用
print(f"Last magician was: {magician}")
嵌套循环与列表推导式: 你可以实现循环的嵌套。此外,Python 支持强大的列表推导式,可以在一行代码中生成列表。
- 语法 :
list = [expression for item in iterable if condition] - 示例:生成 x 为奇数平方,y 为偶数平方的数对。
python
# 列表推导式示例
shudui = [(x**2, y**2) for x in range(11) if x % 2 != 0 for y in range(11) if y % 2 == 0]
print(shudui)
2. while 循环
while 循环在条件满足时一直执行,常用于处理用户输入或修改列表结构。
- 用户交互 :结合
input()函数,可以实现直到用户输入特定指令(如 'quit')才退出的程序。 - 修改列表 :虽然
for循环适合遍历,但在遍历中修改列表会导致追踪困难。while循环更适合在遍历时对列表或字典进行增删改操作。
ini
responses = {}
polling_active = True
while polling_active:
name = input("\nWhat is your name? ")
response = input("Which mountain would you like to climb someday? ")
responses[name] = response
repeat = input("Would you like to let another person respond? (yes/no) ")
if repeat == 'no':
polling_active = False
print("\n--- Poll Results ---")
for name, response in responses.items():
print(f"{name} would like to climb {response}.")
3. 循环控制:break, continue, pass
在循环体中,我们经常需要更精细地控制流程。Python 提供了三个关键字来实现这一点,它们的作用截然不同。
-
break:
- 作用 :立即终止整个循环,跳出循环体,继续执行循环之后的代码。
- 场景 :当你的目标是"找到即停"时,例如在列表中查找某个特定元素,一旦找到就不需要继续遍历剩余的元素,使用
break可以显著提升效率。
python
# 在数字列表中查找 5
numbers = [1, 3, 5, 7, 9, 5]
for num in numbers:
if num == 5:
print(f"找到目标数字 {num},停止查找!")
break # 找到后立即退出循环
print(f"当前检查数字:{num}")
-
continue:
- 作用 :立即跳过本次循环剩余的代码,直接进入下一次循环迭代。循环本身不会终止。
- 场景:当你需要过滤掉某些不符合条件的数据时,例如处理一批文件,跳过所有已标记为"忽略"的文件。
python
# 打印 1 到 10 之间的所有奇数
for i in range(1, 11):
if i % 2 == 0: # 如果是偶数
continue # 跳过本次循环,不执行下面的 print
print(f"奇数:{i}")
-
pass:
- 作用 :不执行任何操作。它是一个空语句,仅仅是为了保持代码结构的完整性,避免语法错误。
- 场景 :当你还在构思代码逻辑,但需要先写一个语法上正确的框架时,可以用
pass来占位。
python
# 规划一个循环,但暂时不写具体逻辑
for i in range(5):
# TODO: 稍后在这里添加处理逻辑
pass
循环控制关键字差异:
虽然 break 和 continue 在 for 和 while 循环中都能使用,但它们的工作机制 和潜在风险在不同循环中存在显著差异。
-
break关键字:表现一致- 行为 :无论是在
for循环还是while循环中,break的作用都是完全相同的:立即终止其所在的整个循环。 - 结论 :你可以放心地在任何循环中使用
break来提前退出,无需担心行为差异。
- 行为 :无论是在
-
continue关键字:机制不同,风险各异-
在
for循环中:- 行为 :当执行
continue时,Python 会立即跳过循环体剩余的代码,然后自动执行迭代器的下一步 (例如,range()生成下一个数字,或列表迭代器移动到下一个元素),再进行下一次循环判断。 - 安全性 :非常安全。你几乎不用担心因为使用
continue而导致死循环,因为迭代器的推进是由 Python 内部自动管理的。
- 行为 :当执行
-
在
while循环中:- 行为 :当执行
continue时,Python 会立即跳过循环体剩余的代码,然后直接返回到循环顶部的条件判断处。 - 风险 :极易导致死循环 。如果循环变量的更新(如
i += 1)写在continue语句之后,那么当continue被执行时,变量更新语句就会被跳过。这会导致循环条件永远无法满足,程序陷入无限循环。
- 行为 :当执行
-
场景对比:使用 continue 跳过偶数
python
# 情况1:在 for 循环中使用 continue - 安全
print("For 循环:")
for i in range(1, 6):
if i % 2 == 0:
continue # 跳过偶数,i 的递增由 range() 自动处理
print(i)
# 输出: 1, 3, 5
# 情况2:在 while 循环中使用 continue - 危险!
print("While 循环 (错误示范):")
i = 1
while i <= 5:
if i % 2 == 0:
continue # 危险!下面的 i += 1 被跳过,i 永远是偶数,导致死循环
print(i)
i += 1 # 这行代码在 i 为偶数时永远不会执行
# 情况3:在 while 循环中正确使用 continue
print("While 循环 (正确示范):")
i = 1
while i <= 5:
if i % 2 == 0:
i += 1 # 在 continue 之前手动更新循环变量
continue
print(i)
i += 1
# 输出: 1, 3, 5
4. for...else 结构
这是 Python 中一个非常独特且常被误解的语法特性。这里的 else 不是 与 if 配对,而是直接与 for 循环绑定。
- 核心逻辑 :
else块中的代码,只有在循环正常结束 (即没有被break打断)时才会执行。所以这里一定要注意与break的配合使用。 - 通俗理解:你可以把它理解为"如果没有找到目标并跳出循环,那么就执行这里的代码"。
场景示例:查找元素 假设我们要在一个数字列表中查找数字 7。如果找到了就打印"找到了",如果遍历完整个列表都没找到,就打印"未找到"。
python
# 情况1:目标存在,循环被 break 打断,else 块不执行
target = 5
for num in [1, 3, 5, 7]:
if num == target:
print(f"找到了目标数字 {target}!")
break
else:
# 只有当循环没有被 break 时才会执行
print(f"列表中没有找到目标数字 {target}。")
# 输出: 找到了目标数字 5!
# 情况2:目标不存在,循环正常遍历完所有元素,else 块执行
target = 9
for num in [1, 3, 5, 7]:
if num == target:
print(f"找到了目标数字 {target}!")
break
else:
# 循环正常结束,说明没有找到目标
print(f"列表中没有找到目标数字 {target}。")
# 输出: 列表中没有找到目标数字 9。
优势 :使用 for...else 可以替代传统的"标志变量"(如 found = False)写法,使代码更加简洁和 Pythonic。它清晰地表达了"搜索失败"这一逻辑分支。
5. for 与 while 的选择:
- 不要在 for 循环中修改列表 :
for循环适合遍历,如果在循环中修改列表(增删元素),会导致 Python 难以追踪元素,容易产生逻辑错误。 - while 的优势 :如果需要动态修改列表或字典的结构,或者需要基于用户输入持续运行程序,请使用
while循环。
条件语句
当程序需要根据不同情况执行不同操作时,条件语句至关重要。
1. 基础结构与冒号规则
Python 的条件判断核心是 if、elif(即 else if)和 else。与其他编程语言(如 C、Java)不同,Python 在语法上有两个非常严格且独特的要求:
-
必须以冒号
:结尾:- 在
if、elif或else语句的末尾,必须加上英文冒号:。 - 原因 :冒号的作用是告诉 Python 解释器,"接下来的代码行将是一个新的逻辑层级(代码块)"。如果没有冒号,解释器无法识别代码块的开始,会直接抛出
SyntaxError: invalid syntax错误。 - 常见错误 :初学者常因习惯 C 系语言的括号
()或忘记输入冒号而导致程序无法运行。
- 在
-
使用缩进而非大括号:
- Python 不使用
{}来包裹代码块,而是完全依赖缩进(通常是 4 个空格)来区分代码的层级。
- Python 不使用
2. 多分支判断 (if-elif-else)
当面临三个或更多可能的情况时,if-elif-else 结构是最佳选择。程序会从上到下依次检查条件,一旦某个条件满足,就执行对应代码块并跳过后续检查。
案例:成绩等级评定 假设我们需要根据用户输入的分数(0-100)输出对应的等级(A, B, C, D, F)。
bash
score = 85
if score >= 90:
print("等级:A (优秀)")
elif score >= 80:
print("等级:B (良好)")
elif score >= 70:
print("等级:C (中等)")
elif score >= 60:
print("等级:D (及格)")
else:
print("等级:F (不及格)")
注意 :在这个例子中,我们不需要写 elif score >= 80 and score < 90。因为 if-elif-else 具有"命中即停"的特性,能执行到 elif score >= 80 这一行,隐含了 score < 90 的前提。
3. 多条件组合判断
在实际开发中,我们经常需要同时满足多个条件,或者满足任意一个条件即可。这时需要使用逻辑运算符 and、or 和 not。
and(与) :所有条件必须同时满足,结果才为True。or(或) :只要有一个条件满足,结果就为True。not(非) :对条件取反。
场景示例:用户登录验证 只有当用户名 和 密码都正确时,才允许登录。
ini
username = "admin"
password = "123456"
# 使用 and 连接两个条件
if username == "admin" and password == "123456":
print("登录成功!")
else:
print("用户名或密码错误。")
4. 条件语句的嵌套
当一个条件满足后,还需要进行更细致的判断,就需要用到嵌套 。即在一个 if 代码块内部,再写一个完整的 if-elif-else 结构。
核心规则:
- 缩进层级:内层代码块必须比外层多一个缩进层级(通常是多 4 个空格)。
- 逻辑流程 :只有外层条件为
True时,才会进入内层进行判断。
场景示例:游乐园门票系统 逻辑如下:
-
首先判断年龄:如果小于 12 岁,免票。
-
如果大于等于 12 岁,再判断是否为工作日:
- 工作日:全价 20 元。
- 周末/节假日:半价 10 元。
python
age = 15
is_weekend = True
if age < 12:
print("小朋友,免费入场!")
else:
# 外层条件满足(年龄>=12),进入内层判断
if is_weekend:
print("票价:10元(周末特惠)")
else:
print("票价:20元(工作日全价)")
最佳实践 :虽然嵌套很有用,但不要嵌套太深 (建议不超过 3 层)。如果嵌套层级过深,代码会变得像"箭头"一样难以阅读(Arrow Code)。此时应考虑使用逻辑运算符(如 and)合并条件,或者将内层逻辑封装成函数。
5. 独立判断 vs 互斥判断
选择使用多个独立的 if 还是 if-elif-else 结构,取决于条件的性质:
| 场景 | 结构选择 | 说明 |
|---|---|---|
| 互斥条件 | if-elif-else |
如年龄分段(18岁就不可能是25岁),满足一个条件后不再检查其他。 |
| 独立条件 | 多个 if |
如披萨配料(可以有玫瑰也可以有康乃馨),每个条件都需要被检查。 |
那么如何进行选择:
- 互斥情况(多选一) :如果条件之间是互斥的(例如:一个人不可能既是 18 岁又是 25 岁),请使用
if-elif-else结构。这样一旦满足某个条件,Python 就会跳过剩余的检查,效率更高。 - 独立情况(多选多) :如果条件之间互不影响(例如:披萨配料,既要玫瑰也要康乃馨),请使用多个独立的
if语句。这样每个条件都会被检查,不会遗漏。
6. 检查列表是否为空
在 Python 中,可以直接在 if 语句中使用列表名。
- 非空列表 :返回
True - 空列表 :返回
False
python
requested_toppings = []
if requested_toppings:
# 列表不为空,执行添加操作
for topping in requested_toppings:
print(f"Adding {topping}.")
else:
# 列表为空
print("Are you sure you want a plain pizza?")