Python3 基础:控制流结构(条件语句、循环)
Python3 基础:控制流结构(条件语句、循环)
- 一、条件语句:程序的决策能力
- if 语句:最基本的条件判断
- if-else 语句:二选一
- if-elif-else 语句:多条件判断
- 嵌套 if 语句:条件中的条件
- 条件表达式(三元运算符):简洁的条件赋值
- 逻辑运算符在条件中的应用
- 成员检测与身份比较
- 二、循环:程序的重复执行能力
- 2.1 for 循环:有限次数的重复
- 遍历字典
- 带索引的遍历:enumerate
- 2.2 while 循环:条件控制的重复
- 无限循环与 break 语句
- continue 语句:跳过当前迭代
- else 子句:循环正常完成时执行
- 三、控制流的高级应用
- 列表推导式:创建列表的简洁方式
- 字典推导式:创建字典的简洁方式
- 生成器表达式:内存高效的迭代
- 嵌套循环:多重迭代
- 四、实用示例:综合应用控制流
- 示例1:简单的猜数字游戏
- 示例2:简易文件处理系统
- 最佳实践与注意事项
- 小结
- 思考题
- 问题1: 如何使用循环计算 1 到 100 的所有偶数的和?
- 问题2: 写一个程序判断一个字符串是否为回文
- 问题3: 使用嵌套循环或列表推导式,生成一个乘法表(九九乘法表)
控制流是任何编程语言的灵魂,它让程序能够做出决策并重复执行任务。想象一下,如果程序只能从头到尾直线执行,那将多么无趣且功能有限!幸运的是,Python 提供了丰富的控制流结构,让我们的代码能够像人类思维一样灵活。
一、条件语句:程序的决策能力
条件语句让程序能够根据不同情况执行不同的操作,就像我们日常生活中的"如果…那么…"决策过程。
if 语句:最基本的条件判断
# 基本的 if 语句
age = 20if age >= 18:print("你已经成年了!")
注意 Python 使用缩进(通常是4个空格)来表示代码块,这是 Python 的特色之一。
if-else 语句:二选一
temperature = 35if temperature > 30:print("今天很热,记得喝水!")
else:print("今天温度适宜。")
if-elif-else 语句:多条件判断
score = 85if 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}")
elif
是 “else if” 的缩写,可以有任意多个 elif
分支。
嵌套 if 语句:条件中的条件
条件语句可以嵌套使用,形成更复杂的决策树:
user_type = "会员"
purchase_amount = 1200if user_type == "会员":if purchase_amount >= 1000:discount = 0.2 # 20% 折扣else:discount = 0.1 # 10% 折扣
else:if purchase_amount >= 1000:discount = 0.1 # 10% 折扣else:discount = 0.05 # 5% 折扣final_amount = purchase_amount * (1 - discount)
print(f"折扣:{discount * 100}%,最终金额:{final_amount}元")
不过要注意,过多的嵌套会让代码难以阅读和维护,应尽量避免过深的嵌套。
条件表达式(三元运算符):简洁的条件赋值
当条件判断只涉及为变量赋值时,可以使用更简洁的条件表达式:
age = 20
status = "成年" if age >= 18 else "未成年"# 相当于:
# if age >= 18:
# status = "成年"
# else:
# status = "未成年"
逻辑运算符在条件中的应用
我们可以使用逻辑运算符 and
、or
和 not
来组合条件:
age = 25
has_ticket = True# 同时满足两个条件
if age >= 18 and has_ticket:print("可以进入电影院。")# 满足至少一个条件
if age < 12 or age >= 65:print("可以享受票价优惠。")# 条件取反
if not has_ticket:print("请先购票。")
成员检测与身份比较
Python 提供了 in
和 is
运算符,在条件语句中非常有用:
# 成员检测:检查元素是否在集合中
fruits = ["苹果", "香蕉", "橙子"]
if "苹果" in fruits:print("有苹果可以吃!")# 身份比较:检查两个对象是否为同一个对象
a = [1, 2, 3]
b = [1, 2, 3]
c = aif a == b: # 值相等print("a 和 b 的值相等")if a is c: # 是同一个对象print("a 和 c 是同一个对象")if a is not b: # 不是同一个对象print("a 和 b 不是同一个对象")
二、循环:程序的重复执行能力
循环让程序能够重复执行代码块,大大提高了编程效率。
2.1 for 循环:有限次数的重复
for
循环用于遍历任何可迭代对象(如列表、元组、字符串等):
# 遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:print(f"我喜欢吃{fruit}")# 遍历字符串中的字符
name = "Python"
for char in name:print(char)# 使用 range() 生成数字序列
for i in range(5): # 生成 0, 1, 2, 3, 4print(i)# 指定 range 的起始值和结束值
for i in range(1, 6): # 生成 1, 2, 3, 4, 5print(i)# 指定步长
for i in range(0, 10, 2): # 生成 0, 2, 4, 6, 8print(i)
遍历字典
person = {"name": "小明","age": 18,"city": "北京"
}# 遍历键
for key in person:print(key)# 遍历值
for value in person.values():print(value)# 同时遍历键和值
for key, value in person.items():print(f"{key}: {value}")
带索引的遍历:enumerate
当需要同时获取元素及其索引时,可以使用 enumerate
函数:
fruits = ["苹果", "香蕉", "橙子"]for index, fruit in enumerate(fruits):print(f"索引 {index}: {fruit}")
2.2 while 循环:条件控制的重复
while
循环会在条件为真时继续执行:
# 基本的 while 循环
count = 0
while count < 5:print(count)count += 1 # 不要忘记更新条件,否则会造成无限循环!
无限循环与 break 语句
有时我们需要无限循环,直到特定条件满足才退出:
# 模拟简单的菜单系统
while True:print("\n1. 开始游戏")print("2. 设置")print("3. 退出")choice = input("请选择:")if choice == "1":print("游戏开始...")elif choice == "2":print("进入设置...")elif choice == "3":print("退出系统...")break # 跳出循环else:print("无效选择,请重试。")
break
语句用于立即跳出循环,不再执行循环中的后续代码。
continue 语句:跳过当前迭代
continue
语句用于跳过当前迭代,直接进入下一次循环:
# 打印 1 到 10 之间的奇数
for i in range(1, 11):if i % 2 == 0: # 如果是偶数continue # 跳过当前迭代print(i)
else 子句:循环正常完成时执行
Python 的循环可以有 else
子句,当循环正常完成(不是通过 break
跳出)时执行:
# 查找列表中的元素
numbers = [1, 3, 5, 7, 9]
search_for = 5for num in numbers:if num == search_for:print(f"找到了 {search_for}!")break
else:print(f"没有找到 {search_for}。")
这个特性在搜索算法中特别有用。
三、控制流的高级应用
列表推导式:创建列表的简洁方式
列表推导式结合了循环和条件表达式,提供了创建列表的简洁方法:
# 生成 1 到 10 的平方列表
squares = [x**2 for x in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 带条件的列表推导式
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(even_squares) # [4, 16, 36, 64, 100]# 相当于:
# even_squares = []
# for x in range(1, 11):
# if x % 2 == 0:
# even_squares.append(x**2)
字典推导式:创建字典的简洁方式
# 创建平方映射字典
square_dict = {x: x**2 for x in range(1, 6)}
print(square_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}# 反转键值对
original = {"a": 1, "b": 2, "c": 3}
inverted = {value: key for key, value in original.items()}
print(inverted) # {1: 'a', 2: 'b', 3: 'c'}
生成器表达式:内存高效的迭代
生成器表达式类似于列表推导式,但使用圆括号而不是方括号,它不会一次性生成所有元素,而是按需生成,更加节省内存:
# 生成器表达式
squares_gen = (x**2 for x in range(1, 1000001))# 使用生成器表达式
for square in squares_gen:if square > 100:breakprint(square)
嵌套循环:多重迭代
有时候需要使用嵌套循环处理多维数据或组合情况:
# 打印乘法表
for i in range(1, 10):for j in range(1, i+1):print(f"{j} × {i} = {i*j}", end="\t")print() # 换行# 生成所有可能的两位数
digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
two_digit_numbers = []for tens in digits:if tens == 0: # 十位不能为0continuefor ones in digits:two_digit_numbers.append(tens * 10 + ones)print(f"两位数的数量:{len(two_digit_numbers)}")
四、实用示例:综合应用控制流
示例1:简单的猜数字游戏
import random# 生成1到100之间的随机数
secret_number = random.randint(1, 100)
attempts = 0
max_attempts = 7print("欢迎玩猜数字游戏!我已经想好了一个1到100之间的数。")
print(f"你有{max_attempts}次机会猜出这个数。")while attempts < max_attempts:try:guess = int(input(f"第{attempts+1}次猜测,请输入你的猜测:"))attempts += 1if guess < secret_number:print("太小了!")elif guess > secret_number:print("太大了!")else:print(f"恭喜你,猜对了!答案就是{secret_number}。")print(f"你用了{attempts}次猜出了答案。")breakexcept ValueError:print("请输入有效的数字!")else: # 尝试次数用完还没猜对print(f"很遗憾,你没有在{max_attempts}次内猜出答案。")print(f"正确答案是{secret_number}。")
示例2:简易文件处理系统
def list_files():print("列出文件...")# 在实际应用中,可以使用 os 模块列出文件def create_file():filename = input("请输入文件名:")content = input("请输入文件内容:")print(f"已创建文件 {filename},内容:{content}")# 在实际应用中,可以使用文件操作函数创建文件def delete_file():filename = input("请输入要删除的文件名:")confirm = input(f"确定要删除 {filename} 吗?(y/n):")if confirm.lower() == 'y':print(f"已删除文件 {filename}")else:print("取消删除操作")# 在实际应用中,可以使用 os 模块删除文件def exit_system():print("感谢使用,再见!")return True# 主循环
def main():functions = {'1': list_files,'2': create_file,'3': delete_file,'4': exit_system}should_exit = Falsewhile not should_exit:print("\n==== 文件管理系统 ====")print("1. 列出文件")print("2. 创建文件")print("3. 删除文件")print("4. 退出系统")choice = input("请选择功能:")if choice in functions:should_exit = functions[choice]()else:print("无效选择,请重试。")# 运行主程序
if __name__ == "__main__":main()
最佳实践与注意事项
- 保持代码可读性:使用适当的缩进和空行,让控制流结构清晰可见。
- 避免无限循环:确保
while
循环的条件最终会变为False
,或者有break
语句跳出循环。 - 谨慎使用嵌套:过多的嵌套会使代码难以阅读和维护,可以考虑提取函数或使用其他控制结构代替深层嵌套。
- 合理使用 break 和 continue:这些语句可以使代码更简洁,但过度使用会破坏代码的线性流程,使逻辑难以追踪。
- 使用 try-except 处理异常情况:特别是在处理用户输入或文件操作时,异常处理可以让程序更加健壮。
- 考虑使用列表推导式和生成器:它们通常比传统的循环更简洁、更高效。
小结
控制流是 Python 编程的核心元素,掌握条件语句和循环结构,可以让你的程序具有决策能力和重复执行能力。通过合理组合这些结构,你可以开发出灵活而强大的程序,处理各种复杂问题。
随着实践经验的积累,你会逐渐掌握何时使用哪种控制结构,如何简化复杂的逻辑,以及如何编写更加优雅、高效的 Python 代码。
思考题
- 如何使用循环计算 1 到 100 的所有偶数的和?
- 写一个程序判断一个字符串是否为回文(正着读和倒着读都一样,如 “radar”)。
- 使用嵌套循环或列表推导式,生成一个乘法表(九九乘法表)。
问题1: 如何使用循环计算 1 到 100 的所有偶数的和?
方法一:使用 for 循环和条件判断
sum_even = 0
for i in range(1, 101):if i % 2 == 0: # 检查是否为偶数sum_even += i
print(sum_even) # 输出: 2550
方法二:直接遍历偶数
sum_even = 0
for i in range(2, 101, 2): # 从2开始,步长为2sum_even += i
print(sum_even) # 输出: 2550
方法三:使用列表推导式和 sum 函数
sum_even = sum([i for i in range(1, 101) if i % 2 == 0])
print(sum_even) # 输出: 2550
方法四:使用数学公式
# 偶数和公式: n(n+1),其中n是最后一个偶数的一半
n = 100 // 2
sum_even = n * (n + 1)
print(sum_even) # 输出: 2550
问题2: 写一个程序判断一个字符串是否为回文
方法一:使用字符串切片
def is_palindrome(s):# 将字符串转换为小写并移除非字母数字字符s = ''.join(c.lower() for c in s if c.isalnum())return s == s[::-1] # 比较原字符串与其反转后的字符串# 测试
print(is_palindrome("radar")) # 输出: True
print(is_palindrome("hello")) # 输出: False
print(is_palindrome("A man, a plan, a canal: Panama")) # 输出: True
方法二:使用双指针技术
def is_palindrome(s):# 将字符串转换为小写并移除非字母数字字符s = ''.join(c.lower() for c in s if c.isalnum())left, right = 0, len(s) - 1while left < right:if s[left] != s[right]:return Falseleft += 1right -= 1return True# 测试
print(is_palindrome("radar")) # 输出: True
print(is_palindrome("hello")) # 输出: False
问题3: 使用嵌套循环或列表推导式,生成一个乘法表(九九乘法表)
方法一:使用嵌套循环
# 打印九九乘法表
for i in range(1, 10):for j in range(1, i + 1):print(f"{j} × {i} = {i*j}", end="\t")print() # 换行
输出:
1 × 1 = 1
1 × 2 = 2 2 × 2 = 4
1 × 3 = 3 2 × 3 = 6 3 × 3 = 9
1 × 4 = 4 2 × 4 = 8 3 × 4 = 12 4 × 4 = 16
1 × 5 = 5 2 × 5 = 10 3 × 5 = 15 4 × 5 = 20 5 × 5 = 25
1 × 6 = 6 2 × 6 = 12 3 × 6 = 18 4 × 6 = 24 5 × 6 = 30 6 × 6 = 36
1 × 7 = 7 2 × 7 = 14 3 × 7 = 21 4 × 7 = 28 5 × 7 = 35 6 × 7 = 42 7 × 7 = 49
1 × 8 = 8 2 × 8 = 16 3 × 8 = 24 4 × 8 = 32 5 × 8 = 40 6 × 8 = 48 7 × 8 = 56 8 × 8 = 64
1 × 9 = 9 2 × 9 = 18 3 × 9 = 27 4 × 9 = 36 5 × 9 = 45 6 × 9 = 54 7 × 9 = 63 8 × 9 = 72 9 × 9 = 81
方法二:使用列表推导式
# 生成九九乘法表作为列表
multiplication_table = [[f"{j} × {i} = {i*j}" for j in range(1, i + 1)]for i in range(1, 10)
]# 打印乘法表
for row in multiplication_table:print("\t".join(row))
方法三:使用列表推导式生成格式化的字符串
# 直接打印格式化的乘法表
print("\n".join(["\t".join([f"{j} × {i} = {i*j}" for j in range(1, i + 1)])for i in range(1, 10)
]))
方法四:传统的九九乘法表格式(中国风格)
for i in range(1, 10):line = ""for j in range(1, i + 1):line += f"{j}×{i}={i*j}\t"print(line)
输出:
1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81