Python流程控制:没有switch、没有do-while,但有for-else和列表推导式
流程控制是程序的骨架,决定了代码的执行顺序。Python的流程控制语法比C语言更简洁,使用缩进代替大括号,并提供了一些独特的特性如for-else、列表推导式等。本篇将详细介绍条件语句、循环语句及其高级用法。
- Python流程控制
1. 条件语句
1.1 if语句
# 基本语法
if 条件:
代码块
# 示例
age = 18
if age >= 18:
print("成年人")
# 与C语言对比
# C: if (age >= 18) { printf("成年人\n"); }
# Python: 无括号,无大括号,用缩进,有冒号
1.2 if-else语句
age = 16
if age >= 18:
print("成年人")
else:
print("未成年人")
# 单行写法(简单情况)
print("成年人" if age >= 18 else "未成年人")
1.3 if-elif-else语句
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"成绩等级:{grade}")
# 注意:Python用elif,不是else if
# C语言:else if
# Python:elif
1.4 条件表达式(三元运算符)
# 语法:值1 if 条件 else 值2
# 基本用法
age = 20
status = "成年" if age >= 18 else "未成年"
# 与C语言对比
# C: status = (age >= 18) ? "成年" : "未成年";
# Python: status = "成年" if age >= 18 else "未成年"
# 嵌套使用(不推荐过度嵌套)
score = 85
grade = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "F"
# 在表达式中使用
numbers = [1, 2, 3, 4, 5]
result = [x * 2 if x % 2 == 0 else x for x in numbers]
# [1, 4, 3, 8, 5]
1.5 match-case语句(Python 3.10+)
Python 3.10引入了结构化模式匹配,类似于C语言的switch-case,但功能更强大。
# 基本用法
def http_status(status):
match status:
case 200:
return "OK"
case 404:
return "Not Found"
case 500:
return "Internal Server Error"
case _: # 默认情况(类似default)
return "Unknown"
print(http_status(200)) # OK
print(http_status(999)) # Unknown
# 匹配多个值
def day_type(day):
match day:
case "Saturday" | "Sunday":
return "周末"
case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
return "工作日"
case _:
return "无效"
# 匹配序列
def process_point(point):
match point:
case (0, 0):
return "原点"
case (0, y):
return f"Y轴上,y={y}"
case (x, 0):
return f"X轴上,x={x}"
case (x, y):
return f"点({x}, {y})"
case _:
return "不是点"
print(process_point((0, 0))) # 原点
print(process_point((0, 5))) # Y轴上,y=5
print(process_point((3, 4))) # 点(3, 4)
# 匹配字典
def process_command(command):
match command:
case {"action": "move", "direction": direction}:
return f"移动方向:{direction}"
case {"action": "attack", "target": target}:
return f"攻击目标:{target}"
case _:
return "未知命令"
# 带守卫条件
def classify_number(n):
match n:
case x if x < 0:
return "负数"
case 0:
return "零"
case x if x > 0:
return "正数"
2. 循环语句
2.1 for循环
Python的for循环用于遍历可迭代对象,与C语言的计数循环不同。
# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# 遍历字符串
for char in "Hello":
print(char)
# 遍历字典
person = {"name": "张三", "age": 25}
for key in person:
print(f"{key}: {person[key]}")
# 遍历字典的键值对
for key, value in person.items():
print(f"{key}: {value}")
# 与C语言对比
# C: for (int i = 0; i < 5; i++) { printf("%d\n", i); }
# Python: for i in range(5): print(i)
2.2 range函数
range()生成整数序列,常用于for循环。
# range(stop):0到stop-1
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# range(start, stop):start到stop-1
for i in range(2, 5):
print(i) # 2, 3, 4
# range(start, stop, step):带步长
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
# 倒序
for i in range(5, 0, -1):
print(i) # 5, 4, 3, 2, 1
# range是惰性的,不会立即生成所有数字
r = range(1000000) # 不占用大量内存
print(500000 in r) # True(快速判断)
# 转换为列表
numbers = list(range(5)) # [0, 1, 2, 3, 4]
2.3 while循环
# 基本语法
count = 0
while count < 5:
print(count)
count += 1
# 无限循环
while True:
user_input = input("输入quit退出:")
if user_input == "quit":
break
print(f"你输入了:{user_input}")
# 条件循环
import random
target = random.randint(1, 100)
guess = 0
while guess != target:
guess = int(input("猜一个数(1-100):"))
if guess < target:
print("太小了")
elif guess > target:
print("太大了")
print("恭喜,猜对了!")
2.4 循环控制:break和continue
# break:跳出循环
for i in range(10):
if i == 5:
break
print(i) # 0, 1, 2, 3, 4
# continue:跳过本次迭代
for i in range(10):
if i % 2 == 0:
continue
print(i) # 1, 3, 5, 7, 9
# 嵌套循环中的break
for i in range(3):
for j in range(3):
if j == 1:
break # 只跳出内层循环
print(f"i={i}, j={j}")
# 跳出多层循环的技巧
# 方法1:使用标志变量
found = False
for i in range(3):
for j in range(3):
if i == 1 and j == 1:
found = True
break
if found:
break
# 方法2:使用函数和return
def find_target():
for i in range(3):
for j in range(3):
if i == 1 and j == 1:
return (i, j)
return None
# 方法3:使用异常(不推荐)
2.5 for-else和while-else
Python独特的特性:循环正常结束(没有被break)时执行else块。
# for-else
for i in range(5):
if i == 10: # 不会触发
break
else:
print("循环正常结束") # 会执行
# 实际应用:查找元素
def find_element(lst, target):
for i, item in enumerate(lst):
if item == target:
print(f"找到了,索引为{i}")
break
else:
print("没找到")
find_element([1, 2, 3, 4, 5], 3) # 找到了,索引为2
find_element([1, 2, 3, 4, 5], 10) # 没找到
# 判断质数
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False # 不是质数
else:
return True # 是质数(循环正常结束)
# while-else
count = 0
while count < 5:
count += 1
else:
print("while循环正常结束")
3. 迭代技巧
3.1 enumerate:带索引遍历
fruits = ["apple", "banana", "cherry"]
# 传统方式
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
# 使用enumerate(推荐)
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 指定起始索引
for i, fruit in enumerate(fruits, start=1):
print(f"{i}: {fruit}")
# 1: apple
# 2: banana
# 3: cherry
3.2 zip:并行遍历
names = ["张三", "李四", "王五"]
ages = [25, 30, 28]
cities = ["北京", "上海", "广州"]
# 并行遍历多个列表
for name, age, city in zip(names, ages, cities):
print(f"{name}, {age}岁, 来自{city}")
# zip返回元组迭代器
pairs = list(zip(names, ages))
# [('张三', 25), ('李四', 30), ('王五', 28)]
# 长度不一致时,以最短的为准
a = [1, 2, 3]
b = [4, 5]
print(list(zip(a, b))) # [(1, 4), (2, 5)]
# 使用zip_longest保留所有元素
from itertools import zip_longest
print(list(zip_longest(a, b, fillvalue=0)))
# [(1, 4), (2, 5), (3, 0)]
# 解压(unzip)
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers, letters = zip(*pairs)
print(numbers) # (1, 2, 3)
print(letters) # ('a', 'b', 'c')
3.3 reversed和sorted
# reversed:反向遍历
for i in reversed(range(5)):
print(i) # 4, 3, 2, 1, 0
for char in reversed("Hello"):
print(char) # o, l, l, e, H
# sorted:排序遍历
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
for n in sorted(numbers):
print(n) # 1, 1, 2, 3, 4, 5, 6, 9
# 降序
for n in sorted(numbers, reverse=True):
print(n)
# 自定义排序
words = ["banana", "Apple", "cherry"]
for w in sorted(words, key=str.lower):
print(w) # Apple, banana, cherry
3.4 字典遍历
person = {"name": "张三", "age": 25, "city": "北京"}
# 遍历键
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}")
# 按键排序遍历
for key in sorted(person.keys()):
print(f"{key}: {person[key]}")
4. 推导式
推导式是Python的特色语法,可以简洁地创建列表、字典、集合。
4.1 列表推导式
# 基本语法:[表达式 for 变量 in 可迭代对象]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 带条件:[表达式 for 变量 in 可迭代对象 if 条件]
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# 条件表达式:[表达式1 if 条件 else 表达式2 for 变量 in 可迭代对象]
labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ['偶数', '奇数', '偶数', '奇数', '偶数']
# 嵌套循环
matrix = [[i * 3 + j for j in range(3)] for i in range(3)]
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
# 展平嵌套列表
nested = [[1, 2], [3, 4], [5, 6]]
flat = [x for sublist in nested for x in sublist]
# [1, 2, 3, 4, 5, 6]
# 与传统循环对比
# 传统写法
squares = []
for x in range(10):
squares.append(x**2)
# 列表推导式
squares = [x**2 for x in range(10)]
4.2 字典推导式
# 基本语法:{键表达式: 值表达式 for 变量 in 可迭代对象}
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 带条件
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# 键值互换
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}
# 从两个列表创建字典
keys = ["name", "age", "city"]
values = ["张三", 25, "北京"]
person = {k: v for k, v in zip(keys, values)}
# {'name': '张三', 'age': 25, 'city': '北京'}
4.3 集合推导式
# 基本语法:{表达式 for 变量 in 可迭代对象}
squares = {x**2 for x in range(-5, 6)}
# {0, 1, 4, 9, 16, 25}(自动去重)
# 带条件
even_squares = {x**2 for x in range(10) if x % 2 == 0}
# {0, 4, 16, 36, 64}
# 从字符串提取唯一字符
text = "hello world"
unique_chars = {c for c in text if c.isalpha()}
# {'h', 'e', 'l', 'o', 'w', 'r', 'd'}
4.4 生成器表达式
生成器表达式类似列表推导式,但使用圆括号,惰性求值,节省内存。
# 语法:(表达式 for 变量 in 可迭代对象)
gen = (x**2 for x in range(10))
print(gen) # <generator object ...>
# 遍历生成器
for value in gen:
print(value)
# 生成器只能遍历一次
gen = (x**2 for x in range(5))
print(list(gen)) # [0, 1, 4, 9, 16]
print(list(gen)) # [](已耗尽)
# 内存效率对比
import sys
# 列表推导式:立即生成所有元素
list_comp = [x**2 for x in range(1000000)]
print(sys.getsizeof(list_comp)) # 约8MB
# 生成器表达式:惰性求值
gen_exp = (x**2 for x in range(1000000))
print(sys.getsizeof(gen_exp)) # 约120字节
# 在函数中使用(可省略括号)
total = sum(x**2 for x in range(10)) # 285
maximum = max(x**2 for x in range(10)) # 81
5. pass语句
pass是空操作语句,用作占位符。
# 空函数
def not_implemented():
pass
# 空类
class MyClass:
pass
# 空循环
for i in range(10):
pass # 什么都不做
# 空条件分支
if condition:
pass # TODO: 待实现
else:
do_something()
# 与C语言对比
# C: 空语句用分号 ;
# Python: 用pass
6. Python vs C语言流程控制对比
| 特性 | C语言 | Python |
|---|---|---|
| 条件语句 | if (cond) { } | if cond: |
| 多分支 | else if | elif |
| switch | switch-case | match-case(3.10+) |
| for循环 | for (i=0; i<n; i++) | for i in range(n): |
| while循环 | while (cond) { } | while cond: |
| 循环else | 无 | for-else, while-else |
| 代码块 | { } | 缩进 |
| 三元运算 | a ? b : c | b if a else c |
代码对比:
// C语言:打印1到10的偶数
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
printf("%d\n", i);
}
}
# Python:打印1到10的偶数
for i in range(1, 11):
if i % 2 == 0:
print(i)
# 更Pythonic的写法
for i in range(2, 11, 2):
print(i)
# 列表推导式
evens = [i for i in range(1, 11) if i % 2 == 0]
print(evens)
7. 常见错误与避坑
❌ 错误1:忘记冒号
# 错误
if x > 0
print("正数") # SyntaxError
# 正确
if x > 0:
print("正数")
❌ 错误2:缩进错误
# 错误:缩进不一致
if True:
print("第一行")
print("第二行") # IndentationError
# 正确
if True:
print("第一行")
print("第二行")
❌ 错误3:在循环中修改列表
# 错误:遍历时删除元素
numbers = [1, 2, 3, 4, 5]
for n in numbers:
if n % 2 == 0:
numbers.remove(n) # 可能跳过元素
print(numbers) # [1, 3, 5](看起来正确,但过程有问题)
# 正确:遍历副本或使用列表推导式
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]
# 或遍历副本
for n in numbers[:]: # 切片创建副本
if n % 2 == 0:
numbers.remove(n)
❌ 错误4:无限循环
# 错误:忘记更新循环变量
i = 0
while i < 5:
print(i)
# 忘记 i += 1,导致无限循环
# 正确
i = 0
while i < 5:
print(i)
i += 1
❌ 错误5:误解for-else
# 错误理解:else在循环结束后总是执行
for i in range(5):
print(i)
else:
print("结束") # 会执行
# 正确理解:else只在没有break时执行
for i in range(5):
if i == 3:
break
else:
print("结束") # 不会执行(因为有break)
8. 实战练习
练习1:九九乘法表
"""
练习:打印九九乘法表
"""
# 方法1:嵌套循环
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}×{i}={i*j:2}", end=" ")
print()
# 方法2:列表推导式
table = [[f"{j}×{i}={i*j}" for j in range(1, i+1)] for i in range(1, 10)]
for row in table:
print(" ".join(row))
练习2:查找质数
"""
练习:找出100以内的所有质数
"""
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
# 方法1:循环
primes = []
for n in range(2, 100):
if is_prime(n):
primes.append(n)
print(primes)
# 方法2:列表推导式
primes = [n for n in range(2, 100) if is_prime(n)]
print(primes)
练习3:猜数字游戏
"""
练习:猜数字游戏
"""
import random
def guess_game():
target = random.randint(1, 100)
attempts = 0
print("我想了一个1-100之间的数字,猜猜看!")
while True:
try:
guess = int(input("你的猜测:"))
attempts += 1
if guess < target:
print("太小了!")
elif guess > target:
print("太大了!")
else:
print(f"恭喜!你用了{attempts}次猜对了!")
break
except ValueError:
print("请输入有效的数字!")
# guess_game()
练习4:统计字符
"""
练习:统计文本中各字符出现次数
"""
text = "Hello, World! Hello, Python!"
# 方法1:字典
char_count = {}
for char in text.lower():
if char.isalpha():
char_count[char] = char_count.get(char, 0) + 1
for char, count in sorted(char_count.items()):
print(f"'{char}': {count}")
# 方法2:Counter
from collections import Counter
char_count = Counter(c for c in text.lower() if c.isalpha())
print(char_count.most_common())
9. 总结
🔑 核心要点
| 知识点 | 要点 |
|---|---|
| if语句 | 用冒号和缩进,elif不是else if |
| for循环 | 遍历可迭代对象,不是计数循环 |
| while循环 | 条件循环,注意避免无限循环 |
| break/continue | 跳出循环/跳过本次迭代 |
| for-else | 循环正常结束时执行else |
| enumerate | 带索引遍历 |
| zip | 并行遍历多个序列 |
| 推导式 | 简洁创建列表/字典/集合 |
| match-case | 结构化模式匹配(3.10+) |
✅ 学习检查清单
- 掌握if-elif-else语句
- 掌握for循环和range函数
- 掌握while循环
- 理解break、continue的作用
- 理解for-else的含义
- 熟练使用enumerate和zip
- 掌握列表推导式
- 了解生成器表达式
📖 下一步学习
掌握了流程控制后,让我们学习Python的函数:
常见问题 FAQ
💬 Python为什么没有switch语句?
Python 3.10+引入了match-case语法,比C的switch更强大,支持模式匹配。3.10之前通常用if-elif-else或字典映射替代。
💬 for-else是什么意思?
for-else中的else在循环正常结束(没有被break打断)时执行。典型用法是搜索场景:循环找到了就break,没找到就走else分支。
� 系列导航
- 上一篇:06 - Python运算符与表达式
- 当前:07 - Python流程控制
- 下一篇:08 - Python函数基础