控制流
控制流决定了程序的执行顺序,包括条件判断和循环。Python 提供了简洁而强大的控制流语句。
条件语句
条件语句根据不同的条件执行不同的代码块。
if 语句
最基本的条件语句。
age = 18
if age >= 18:
print("你已经成年")
print("可以考取驾照")
# 注意:冒号和缩进是必须的
if-else 语句
二选一的条件判断。
age = 16
if age >= 18:
print("你已经成年")
else:
print("你还未成年")
print("需要等待成年")
# 三元表达式(条件表达式)
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 成年
if-elif-else 语句
多选一的条件判断。
score = 85
if score >= 90:
grade = 'A'
print("优秀")
elif score >= 80:
grade = 'B'
print("良好")
elif score >= 70:
grade = 'C'
print("中等")
elif score >= 60:
grade = 'D'
print("及格")
else:
grade = 'F'
print("不及格")
print(f"成绩等级: {grade}")
嵌套条件
在条件语句中嵌套另一个条件语句。
age = 25
has_license = True
if age >= 18:
print("你已经成年")
if has_license:
print("你可以开车")
else:
print("你需要先考取驾照")
else:
print("你还未成年")
# 嵌套的多元条件
temperature = 25
weather = "晴天"
if temperature > 30:
if weather == "晴天":
print("天气炎热,注意防晒")
else:
print("天气闷热")
elif temperature >= 20:
if weather == "晴天":
print("天气舒适,适合外出")
else:
print("天气凉爽,带把伞")
else:
print("天气较冷,注意保暖")
比较运算符
Python 中的比较运算符用于比较值。
x = 10
y = 20
# 等于
print(x == y) # False
# 不等于
print(x != y) # True
# 大于
print(x > y) # False
# 小于
print(x < y) # True
# 大于等于
print(x >= 10) # True
# 小于等于
print(y <= 20) # True
# 链式比较
age = 25
print(18 <= age <= 65) # True(年龄在18到65之间)
# 多个比较
print(1 < 2 < 3 < 4) # True
逻辑运算符
用于组合多个条件。
age = 25
has_license = True
has_car = False
# and(与):两个条件都为 True
if age >= 18 and has_license:
print("可以开车")
# or(或):至少一个条件为 True
if has_license or has_car:
print("你有车或驾照")
# not(非):取反
if not has_car:
print("你没有车")
# 组合使用
if age >= 18 and has_license and not has_car:
print("你有驾照但没有车")
# 短路求值
print(True and print("Hello")) # 输出: Hello(因为需要判断右边)
print(False and print("World")) # 不输出(短路,不需要判断右边)
print(True or print("Python")) # 不输出(短路)
print(False or print("Java")) # 输出: Java
成员运算符
测试序列中是否存在某个值。
# in:检查是否存在
fruits = ["apple", "banana", "orange"]
print("apple" in fruits) # True
print("grape" in fruits) # False
# not in:检查是否不存在
print("grape" not in fruits) # True
# 字符串中
text = "Hello, World!"
print("Hello" in text) # True
print("Python" in text) # False
# 字典中(检查键)
person = {"name": "Alice", "age": 25}
print("name" in person) # True
print("email" in person) # False
身份运算符
比较两个对象的内存地址。
a = [1, 2, 3]
b = [1, 2, 3]
c = a
# is:检查是否是同一个对象
print(a is c) # True(指向同一个对象)
print(a is b) # False(不同的对象,即使值相同)
# is not:检查是否不是同一个对象
print(a is not b) # True
# 与 == 的区别
print(a == b) # True(值相同)
print(a is b) # False(不是同一个对象)
# None 的判断(推荐使用 is)
value = None
if value is None:
print("value 是 None")
if value is not None:
print("value 不是 None")
# 小整数缓存(-5 到 256)
x = 256
y = 256
print(x is y) # True
x = 257
y = 257
print(x is y) # False(在小整数范围之外)
真值测试
Python 中的值可以被当作布尔值使用。
# 假值(Falsy):在布尔上下文中被当作 False
print(bool(False)) # False
print(bool(None)) # False
print(bool(0)) # False
print(bool(0.0)) # False
print(bool("")) # False(空字符串)
print(bool([])) # False(空列表)
print(bool(())) # False(空元组)
print(bool({})) # False(空字典)
print(bool(set())) # False(空集合)
# 真值(Truthy):在布尔上下文中被当作 True
print(bool(True)) # True
print(bool(1)) # True
print(bool(3.14)) # True
print(bool("hello")) # True
print(bool([1, 2])) # True
print(bool((1, 2))) # True
print(bool({"a": 1})) # True
# 在条件语句中使用
data = [1, 2, 3]
if data: # 等价于 if len(data) > 0
print("列表不为空")
value = 0
if not value: # 等价于 if value == 0
print("value 是 0")
# 使用真值测试简化代码
name = ""
if name: # 比起 if name != "" 更简洁
print(f"你好, {name}")
else:
print("请提供名字")
循环语句
循环用于重复执行代码块。
for 循环
for 循环用于遍历序列(列表、元组、字符串等)。
遍历序列
# 遍历列表
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# 遍历字符串
for char in "Python":
print(char)
# 遍历元组
coordinates = (1, 2, 3)
for coord in coordinates:
print(coord)
# 遍历字典(默认遍历键)
person = {"name": "Alice", "age": 25, "city": "New York"}
for key in person:
print(key)
# 遍历字典的值
for value in person.values():
print(value)
# 遍历字典的键值对
for key, value in person.items():
print(f"{key}: {value}")
range() 函数
range() 用于生成数字序列。
# 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(1, 6):
print(i) # 1, 2, 3, 4, 5
# 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
# 创建列表
numbers = list(range(5))
print(numbers) # [0, 1, 2, 3, 4]
# 大范围的 range
for i in range(1000000):
if i >= 5:
break
print(i) # 0, 1, 2, 3, 4
# range 不会一次性生成所有数字,节省内存
enumerate() 函数
遍历时同时获取索引和值。
fruits = ["apple", "banana", "orange"]
# enumerate 返回 (索引, 值) 的元组
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 输出:
# 0: apple
# 1: banana
# 2: orange
# 指定起始索引
for index, fruit in enumerate(fruits, start=1):
print(f"{index}. {fruit}")
# 输出:
# 1. apple
# 2. banana
# 3. orange
# 手动获取索引(不推荐)
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
zip() 函数
同时遍历多个序列。
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Paris"]
# zip 将多个序列打包成元组
for name, age, city in zip(names, ages, cities):
print(f"{name}, {age}岁, 来自{city}")
# 输出:
# Alice, 25岁, 来自New York
# Bob, 30岁, 来自London
# Charlie, 35岁, 来自Paris
# 创建字典
keys = ["name", "age", "city"]
values = ["Alice", 25, "New York"]
person = dict(zip(keys, values))
print(person) # {'name': 'Alice', 'age': 25, 'city': 'New York'}
# zip 在最短的序列耗尽时停止
list1 = [1, 2, 3, 4]
list2 = ['a', 'b', 'c']
for num, letter in zip(list1, list2):
print(num, letter)
# 输出:
# 1 a
# 2 b
# 3 c
# 4 不会被遍历
# zip_longest(来自 itertools)
from itertools import zip_longest
for num, letter in zip_longest(list1, list2, fillvalue=None):
print(num, letter)
# 输出:
# 1 a
# 2 b
# 3 c
# 4 None
嵌套循环
循环中可以包含另一个循环。
# 打印乘法表(9x9)
for i in range(1, 10):
for j in range(1, 10):
print(f"{i}x{j}={i*j:2d}", end=" ")
print() # 换行
# 遍历嵌套列表
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for row in matrix:
for element in row:
print(element, end=" ")
print()
# 扁平化嵌套列表
nested = [[1, 2], [3, 4], [5, 6]]
flattened = []
for sublist in nested:
for item in sublist:
flattened.append(item)
print(flattened) # [1, 2, 3, 4, 5, 6]
while 循环
while 循环在条件为 True 时重复执行代码块。
基本语法
# 基本用法
count = 0
while count < 5:
print(count)
count += 1
# 输出: 0, 1, 2, 3, 4
# 计算总和
total = 0
number = 1
while number <= 10:
total += number
number += 1
print(f"1到10的和: {total}") # 55
# 用户输入验证
while True:
age = input("请输入年龄: ")
if age.isdigit():
age = int(age)
if age >= 0 and age <= 120:
print(f"你的年龄是: {age}")
break
else:
print("年龄必须在0到120之间")
else:
print("请输入有效的数字")
无限循环
条件永远为 True 的循环。
# 使用 break 退出
while True:
user_input = input("输入 'quit' 退出: ")
if user_input == "quit":
break
print(f"你输入了: {user_input}")
# 使用标志变量
running = True
while running:
user_input = input("输入 'quit' 退出: ")
if user_input == "quit":
running = False
else:
print(f"你输入了: {user_input}")
while-else 循环
else 块在循环正常结束时执行(被 break 跳过则不执行)。
# 查找数字
numbers = [1, 3, 5, 7, 9]
target = 5
index = 0
while index < len(numbers):
if numbers[index] == target:
print(f"找到 {target} 在索引 {index}")
break
index += 1
else:
print(f"没有找到 {target}")
# 如果 target 存在,输出: 找到 5 在索引 2
# 如果 target 不存在,输出: 没有找到 X
for vs while
# for 循环:适合遍历已知序列
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# 等价的 while 循环
fruits = ["apple", "banana", "orange"]
index = 0
while index < len(fruits):
print(fruits[index])
index += 1
# 选择建议:
# - 知道迭代次数或遍历序列:使用 for
# - 不确定迭代次数:使用 while
循环控制
循环控制语句用于改变循环的执行流程。
break
break 用于立即退出循环。
# 在 for 循环中使用 break
for i in range(10):
if i == 5:
break
print(i)
# 输出: 0, 1, 2, 3, 4
# 在 while 循环中使用 break
count = 0
while True:
print(count)
count += 1
if count >= 5:
break
# 输出: 0, 1, 2, 3, 4
# 查找元素
fruits = ["apple", "banana", "orange"]
search = "banana"
for fruit in fruits:
if fruit == search:
print(f"找到 {search}")
break
else:
print(f"没有找到 {search}")
# 嵌套循环中的 break(只退出内层循环)
for i in range(3):
for j in range(3):
if j == 1:
break
print(f"i={i}, j={j}")
# 输出:
# i=0, j=0
# i=1, j=0
# i=2, j=0
continue
continue 用于跳过当前迭代,继续下一次迭代。
# 在 for 循环中使用 continue
for i in range(10):
if i % 2 == 0:
continue # 跳过偶数
print(i)
# 输出: 1, 3, 5, 7, 9
# 在 while 循环中使用 continue
count = 0
while count < 10:
count += 1
if count % 2 == 0:
continue
print(count)
# 输出: 1, 3, 5, 7, 9
# 过滤数据
numbers = [1, -2, 3, -4, 5, -6]
for num in numbers:
if num < 0:
continue # 跳过负数
print(f"正数: {num}")
# 输出:
# 正数: 1
# 正数: 3
# 正数: 5
# 处理无效数据
data = ["alice", "BOB", "charlie", "DAVID", "eve"]
names = []
for name in data:
if name.isupper():
continue # 跳过大写名字
names.append(name.capitalize())
print(names) # ['Alice', 'Charlie', 'Eve']
else 子句
else 块在循环正常结束时执行(未被 break 中断)。
# for-else
for i in range(5):
print(i)
else:
print("循环正常结束")
# 输出: 0, 1, 2, 3, 4, 循环正常结束
# 被 break 中断时不执行 else
for i in range(5):
if i == 3:
break
print(i)
else:
print("这不会执行")
# 输出: 0, 1, 2
# 实际应用:查找质数
for num in range(2, 10):
for i in range(2, num):
if num % i == 0:
print(f"{num} = {i} x {num//i}")
break
else:
print(f"{num} 是质数")
# 输出:
# 2 是质数
# 3 是质数
# 4 = 2 x 2
# 5 是质数
# 6 = 2 x 3
# 7 是质数
# 8 = 2 x 4
# 9 = 3 x 3
# while-else
count = 0
while count < 5:
print(count)
count += 1
else:
print("计数完成")
# 输出: 0, 1, 2, 3, 4, 计数完成
pass 语句
pass 是空操作,用作占位符。
# 什么都不做
if True:
pass
# 空函数(待实现)
def my_function():
pass
# 空类(待实现)
class MyClass:
pass
# 占位符
for i in range(10):
pass # TODO: 实现具体逻辑
# 在异常处理中
try:
# 尝试某些操作
pass
except:
pass # 暂时不处理异常
列表推导式
列表推导式是创建列表的简洁方式。
基本语法
# 基本形式:[expression for item in iterable]
# 创建 0-9 的平方列表
squares = [x ** 2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 等价的传统写法
squares = []
for x in range(10):
squares.append(x ** 2)
# 转换列表
words = ["hello", "world", "python"]
upper_words = [word.upper() for word in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']
# 计算表达式
prices = [100, 200, 300]
discounted = [price * 0.9 for price in prices]
print(discounted) # [90.0, 180.0, 270.0]
带条件的推导式
# 带过滤条件:[expression for item in iterable if condition]
# 获取偶数
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
# 过滤字符串
words = ["hello", "world", "python", "is", "awesome"]
long_words = [word for word in words if len(word) > 5]
print(long_words) # ['python', 'awesome']
# 复杂条件
numbers = list(range(20))
result = [x for x in numbers if x % 2 == 0 and x % 3 == 0]
print(result) # [0, 6, 12, 18]
# 使用函数过滤
def is_valid(value):
return value > 0 and value < 100
values = [-5, 10, 50, 100, 150]
valid = [v for v in values if is_valid(v)]
print(valid) # [10, 50]
带表达式的推导式
# if-else 表达式:[value_if_true if condition else value_if_false for item in iterable]
# 分类数字
numbers = [1, 2, 3, 4, 5, 6]
result = ["偶数" if x % 2 == 0 else "奇数" for x in numbers]
print(result) # ['奇数', '偶数', '奇数', '偶数', '奇数', '偶数']
# 处理 None 值
values = [1, None, 3, None, 5]
processed = [x if x is not None else 0 for x in values]
print(processed) # [1, 0, 3, 0, 5]
# 条件表达式
numbers = [1, 2, 3, 4, 5]
adjusted = [x * 2 if x < 3 else x + 10 for x in numbers]
print(adjusted) # [2, 4, 13, 14, 15]
嵌套推导式
# 嵌套循环:[expression for item1 in iterable1 for item2 in iterable2]
# 生成所有组合
colors = ["红", "蓝", "绿"]
sizes = ["S", "M", "L"]
combinations = [f"{color}{size}" for color in colors for size in sizes]
print(combinations)
# ['红S', '红M', '红L', '蓝S', '蓝M', '蓝L', '绿S', '绿M', '绿L']
# 等价的传统写法
combinations = []
for color in colors:
for size in sizes:
combinations.append(f"{color}{size}")
# 矩阵转置
matrix = [[1, 2, 3], [4, 5, 6]]
transposed = [[row[i] for row in matrix] for i in range(3)]
print(transposed) # [[1, 4], [2, 5], [3, 6]]
# 扁平化嵌套列表
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [item for sublist in nested for item in sublist]
print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
其他推导式
字典推导式
# 基本语法:{key_expression: value_expression for item in iterable}
# 创建字典
squares = {x: x ** 2 for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 从列表创建
words = ["apple", "banana", "cherry"]
word_lengths = {word: len(word) for word in words}
print(word_lengths) # {'apple': 5, 'banana': 6, 'cherry': 6}
# 带条件
numbers = [1, 2, 3, 4, 5, 6]
even_squares = {x: x ** 2 for x in numbers if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36}
# 交换键值
original = {1: "one", 2: "two", 3: "three"}
swapped = {v: k for k, v in original.items()}
print(swapped) # {'one': 1, 'two': 2, 'three': 3}
集合推导式
# 基本语法:{expression for item in iterable}
# 创建集合
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16}(自动去重)
# 带条件
numbers = range(10)
even_cubes = {x ** 3 for x in numbers if x % 2 == 0}
print(even_cubes) # {0, 8, 64, 216, 512}
# 字符串处理
text = "Hello World"
unique_chars = {char.lower() for char in text if char.isalpha()}
print(unique_chars) # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}
生成器表达式
# 基本语法:(expression for item in iterable)
# 使用圆括号而不是方括号
# 惰性求值,节省内存
# 生成器表达式
squares_gen = (x ** 2 for x in range(10))
print(squares_gen) # <generator object ...>
print(list(squares_gen)) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 直接使用
squares_gen = (x ** 2 for x in range(10))
for square in squares_gen:
print(square)
# 作为函数参数
numbers = [1, 2, 3, 4, 5]
total = sum(x ** 2 for x in numbers)
print(total) # 55
# 处理大文件(不需要一次性加载所有行)
# 假设有一个大文件
# lines = (line.strip() for line in open("large_file.txt"))
# for line in lines:
# process(line)
# 生成器表达式 vs 列表推导式
import sys
# 列表推导式(立即创建列表)
list_comp = [x ** 2 for x in range(100000)]
print(sys.getsizeof(list_comp)) # 约 800KB+
# 生成器表达式(不立即创建)
gen_expr = (x ** 2 for x in range(100000))
print(sys.getsizeof(gen_expr)) # 约 200B(字节)
控制流最佳实践
1. 避免深层嵌套
# 不推荐:深层嵌套
if user:
if user.is_active:
if user.has_permission:
if user.can_edit:
print("可以编辑")
else:
print("不能编辑")
else:
print("没有权限")
else:
print("用户未激活")
else:
print("用户不存在")
# 推荐:提前返回(Guard Clauses)
if not user:
print("用户不存在")
return
if not user.is_active:
print("用户未激活")
return
if not user.has_permission:
print("没有权限")
return
if not user.can_edit:
print("不能编辑")
return
print("可以编辑")
# 推荐:使用任意函数
def can_edit_content(user):
if not user or not user.is_active:
return False
return user.has_permission and user.can_edit
if can_edit_content(user):
print("可以编辑")
2. 使用 for 而不是 while
# 不推荐
index = 0
while index < len(items):
print(items[index])
index += 1
# 推荐
for item in items:
print(item)
# 不推荐
count = 0
while count < 10:
print(count)
count += 1
# 推荐
for count in range(10):
print(count)
3. 使用枚举而不是手动索引
# 不推荐
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
# 推荐
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
4. 利用真值测试
# 不推荐
if len(items) > 0:
print("列表不为空")
if value == 0:
print("value 是 0")
# 推荐
if items:
print("列表不为空")
if not value:
print("value 是 0")
5. 使用推导式简化代码
# 不推荐
squares = []
for i in range(10):
squares.append(i ** 2)
# 推荐
squares = [i ** 2 for i in range(10)]
# 不推荐
evens = []
for i in range(10):
if i % 2 == 0:
evens.append(i)
# 推荐
evens = [i for i in range(10) if i % 2 == 0]
6. 合理使用 else 子句
# for-else 适用于查找失败的情况
for item in items:
if item == target:
print("找到")
break
else:
print("未找到")
# 而不是:
found = False
for item in items:
if item == target:
print("找到")
found = True
break
if not found:
print("未找到")
7. 避免在循环中修改正在遍历的序列
# 错误:在遍历时修改列表
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num) # 可能导致问题
# 正确:创建副本或使用列表推导式
numbers = [1, 2, 3, 4, 5]
numbers = [num for num in numbers if num % 2 != 0]
# 或创建副本
numbers = [1, 2, 3, 4, 5]
for num in numbers[:]: # 遍历副本
if num % 2 == 0:
numbers.remove(num)
小结
本章节介绍了 Python 的控制流:
- **条件语句**: if, if-else, if-elif-else, 嵌套条件, 三元表达式
- **比较运算符**: ==, !=, >, <, >=, <=
- **逻辑运算符**: and, or, not
- **成员运算符**: in, not in
- **身份运算符**: is, is not
- **真值测试**: Python 中的真值和假值
- **for 循环**: 遍历序列, range(), enumerate(), zip(), 嵌套循环
- **while 循环**: 基本语法, 无限循环, while-else
- **循环控制**: break, continue, else 子句, pass
- **列表推导式**: 基本语法, 带条件, 嵌套, 其他推导式(字典, 集合, 生成器)
掌握控制流是编写复杂 Python 程序的基础。下一章我们将学习函数,包括函数定义、参数、作用域等。