目录

第二章 控制流

本章概要

控制流是编程的核心概念,它决定了程序执行的顺序和路径。本章将深入学习Python中的条件语句、循环结构和推导式,让你能够编写更复杂的程序逻辑。

2.1 条件语句

2.1.1 if 语句

最基本的条件语句,当条件为真时执行代码块。

age = 18
 
if age >= 18:
    print("你已经成年了")

2.1.2 if-else 语句

提供两个执行分支。

age = 16
 
if age >= 18:
    print("你已经成年了")
else:
    print("你还未成年")

2.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}")

2.1.4 嵌套条件语句

在条件语句内部再写条件语句。

age = 25
has_id = True
 
if age >= 18:
    if has_id:
        print("可以进入")
    else:
        print("请出示证件")
else:
    print("未成年人禁止进入")

2.1.5 三元表达式

简洁的条件表达式。

age = 20
status = "成年" if age >= 18 else "未成年"
print(status)  # 成年
 
# 等效于
if age >= 18:
    status = "成年"
else:
    status = "未成年"

2.1.6 条件判断的真值

以下值被视为 ``False``:

# 假值
False
None
0
0.0
0j  # 复数0
""  # 空字符串
[]  # 空列表
{}  # 空字典
()  # 空元组
set()  # 空集合
 
# 示例
name = ""
if not name:
    print("名字不能为空")
 
items = []
if not items:
    print("列表为空")

2.1.7 逻辑组合条件

# and - 两个条件都满足
age = 25
income = 5000
if age >= 18 and income >= 3000:
    print("符合贷款条件")
 
# or - 任一条件满足
weekend = True
holiday = False
if weekend or holiday:
    print("今天休息")
 
# not - 条件取反
is_closed = False
if not is_closed:
    print("商店营业中")
 
# 组合使用
x = 15
if (x > 10 and x < 20) or x == 0:
    print("x在10到20之间,或x等于0")

2.1.8 match-case 结构(Python 3.10+)

结构模式匹配,类似于其他语言的switch语句。

def http_status(status):
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Server Error"
        case _:
            return "Unknown Status"
 
# 带守卫子句的匹配
def describe_number(n):
    match n:
        case 0:
            return "零"
        case x if x > 0:
            return f"正数: {x}"
        case x if x < 0:
            return f"负数: {x}"
 
# 匹配数据结构
def handle_command(command):
    match command:
        case ["load", filename]:
            print(f"加载文件: {filename}")
        case ["save", filename]:
            print(f"保存文件: {filename}")
        case ["quit"]:
            print("退出程序")
        case _:
            print("未知命令")
 
handle_command(["load", "data.txt"])

2.2 循环语句

2.2.1 while 循环

当条件为真时重复执行代码块。

# 基本while循环
count = 0
while count < 5:
    print(f"计数: {count}")
    count += 1
 
print("循环结束")

while-else 结构

当循环正常结束时(没有被break),执行else块。

# 查找列表中的第一个负数
numbers = [1, 2, 3, 4, 5]
i = 0
 
while i < len(numbers):
    if numbers[i] < 0:
        print(f"找到负数: {numbers[i]}")
        break
    i += 1
else:
    print("列表中没有负数")

无限循环

# 用户输入直到输入'quit'
while True:
    command = input("请输入命令 (quit退出): ")
    if command.lower() == "quit":
        print("程序退出")
        break
    print(f"执行命令: {command}")

2.2.2 for 循环

遍历序列或其他可迭代对象。

# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
 
# 遍历字符串
for char in "Python":
    print(char, end=" ")  # P y t h o n
 
# 遍历字典
student = {"name": "Alice", "age": 20, "grade": "A"}
for key in student:
    print(f"{key}: {student[key]}")
 
# 遍历键值对
for key, value in student.items():
    print(f"{key}: {value}")

range() 函数

生成数字序列。

# range(stop)
for i in range(5):
    print(i, end=" ")  # 0 1 2 3 4
 
# range(start, stop)
for i in range(2, 6):
    print(i, end=" ")  # 2 3 4 5
 
# range(start, stop, step)
for i in range(0, 10, 2):
    print(i, end=" ")  # 0 2 4 6 8
 
# 倒序
for i in range(10, 0, -1):
    print(i, end=" ")  # 10 9 8 7 6 5 4 3 2 1

enumerate() 函数

同时获取索引和值。

fruits = ["apple", "banana", "cherry"]
 
# 使用enumerate
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")
 
# 指定起始索引
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")

zip() 函数

并行遍历多个序列。

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["北京", "上海", "广州"]
 
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, 来自{city}")
 
# zip对象可以转换为列表/字典
pairs = list(zip(names, ages))
print(pairs)  # [('Alice', 25), ('Bob', 30), ('Charlie', 35)]

2.2.3 循环控制语句

break 语句

立即退出循环。

# 查找第一个大于10的数
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
 
for num in numbers:
    if num > 10:
        print(f"找到: {num}")
        break

continue 语句

跳过当前迭代,继续下一次循环。

# 打印奇数
for i in range(10):
    if i % 2 == 0:
        continue
    print(i, end=" ")  # 1 3 5 7 9

pass 语句

占位符,不做任何事情。

# 待实现的函数
def future_function():
    pass  # 稍后实现
 
# 空的循环体
for i in range(10):
    pass  # 暂不处理

嵌套循环

# 打印乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j:2d}", end=" ")
    print()
 
# 遍历二维列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for row in matrix:
    for item in row:
        print(item, end=" ")
    print()

2.2.4 循环中的else子句

# 查找质数
for n in range(2, 20):
    for x in range(2, n):
        if n % x == 0:
            print(f"{n} = {x} * {n//x}")
            break
    else:
        # 循环没有被break,说明是质数
        print(f"{n} 是质数")

2.3 推导式

推导式(Comprehension)是Python特有的简洁语法,用于从可迭代对象创建新的数据结构。

2.3.1 列表推导式

基本语法:

[表达式 for 变量 in 可迭代对象 if 条件]

示例:

# 创建平方数列表
squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
 
# 带条件的列表推导式
evens = [x for x in range(20) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
 
# 处理字符串
words = ["Hello", "World", "Python", "Programming"]
lengths = [len(word) for word in words]
print(lengths)  # [5, 5, 6, 11]
 
# 嵌套列表推导式
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
print(matrix)  # [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
 
# 展平嵌套列表
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [item for sublist in nested for item in sublist]
print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

2.3.2 字典推导式

# 基本语法:{键: 值 for 变量 in 可迭代对象}
 
# 创建平方数字典
squares_dict = {x: x**2 for x in range(6)}
print(squares_dict)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
 
# 交换键值
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped)  # {1: 'a', 2: 'b', 3: 'c'}
 
# 过滤字典
scores = {"Alice": 85, "Bob": 92, "Charlie": 78, "David": 95}
passed = {k: v for k, v in scores.items() if v >= 80}
print(passed)  # {'Alice': 85, 'Bob': 92, 'David': 95}

2.3.3 集合推导式

# 基本语法:{表达式 for 变量 in 可迭代对象}
 
# 创建平方集合
squares_set = {x**2 for x in range(20)}
print(squares_set)  # 去重后的平方数
 
# 从字符串创建集合
chars = {c.lower() for c in "Hello World" if c.isalpha()}
print(chars)  # {'h', 'e', 'l', 'o', 'w', 'r', 'd'}

2.3.4 生成器表达式

与列表推导式类似,但返回生成器对象,惰性求值,节省内存。

# 生成器表达式
squares_gen = (x**2 for x in range(1000000))
 
# 逐个获取值
print(next(squares_gen))  # 0
print(next(squares_gen))  # 1
 
# 在循环中使用
for square in (x**2 for x in range(10)):
    print(square, end=" ")  # 0 1 4 9 16 25 36 49 64 81
 
# 与sum()等函数配合使用
total = sum(x**2 for x in range(1000))
print(f"\n0到999的平方和: {total}")

2.3.5 推导式 vs 循环

比较:

# 传统循环方式
evens = []
for x in range(20):
    if x % 2 == 0:
        evens.append(x)
 
# 列表推导式(更简洁、更快)
evens = [x for x in range(20) if x % 2 == 0]

何时使用推导式:

何时使用循环:

2.4 代码示例

示例1:猜数字游戏

import random
 
secret = random.randint(1, 100)
attempts = 0
max_attempts = 7
 
print("猜数字游戏!我想了一个1到100之间的数字。")
 
while attempts < max_attempts:
    guess = int(input(f"第{attempts + 1}次尝试,请输入你的猜测: "))
    attempts += 1
 
    if guess < secret:
        print("太小了!")
    elif guess > secret:
        print("太大了!")
    else:
        print(f"恭喜你猜对了!答案就是{secret}。")
        print(f"你用了{attempts}次猜中。")
        break
else:
    print(f"游戏结束!正确答案是{secret}。")

示例2:斐波那契数列

def fibonacci(n):
    """生成前n个斐波那契数"""
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b
 
# 打印前20个斐波那契数
print("斐波那契数列:")
for i, num in enumerate(fibonacci(20), 1):
    print(f"F({i}) = {num}")

示例3:文本分析器

text = """
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。
Python由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年。
Python源代码遵循GPL协议。
"""
 
# 统计字符
char_count = len(text)
print(f"总字符数: {char_count}")
 
# 统计单词
words = text.split()
word_count = len(words)
print(f"单词数: {word_count}")
 
# 统计行数
lines = text.strip().split('\n')
line_count = len(lines)
print(f"行数: {line_count}")
 
# 统计每个字符出现的频率(只统计字母)
from collections import Counter
letters = [c.lower() for c in text if c.isalpha()]
frequency = Counter(letters)
print("\n字符频率(前10):")
for char, count in frequency.most_common(10):
    print(f"  {char}: {count}")

2.5 练习题

练习1:九九乘法表

使用嵌套循环打印九九乘法表。

# 参考答案
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j:2d}", end=" ")
    print()

练习2:判断质数

编写函数判断一个数是否为质数。

# 参考答案
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
 
# 测试
for num in range(1, 101):
    if is_prime(num):
        print(num, end=" ")

练习3:列表去重并排序

使用集合推导式去除列表中的重复元素并排序。

# 参考答案
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
 
# 方法1:使用集合推导式
unique_sorted = sorted({x for x in numbers})
print(unique_sorted)  # [1, 2, 3, 4, 5, 6, 9]
 
# 方法2:使用dict.fromkeys()(保持插入顺序)
unique_ordered = list(dict.fromkeys(numbers))
print(unique_ordered)  # [3, 1, 4, 5, 9, 2, 6]

练习4:打印金字塔

编写程序打印金字塔图案。

# 参考答案
def print_pyramid(height):
    for i in range(height):
        spaces = " " * (height - i - 1)
        stars = "*" * (2 * i + 1)
        print(spaces + stars)
 
print_pyramid(5)
# 输出:
#     *
#    ***
#   *****
#  *******
# *********

练习5:回文检查

编写函数检查字符串是否为回文。

# 参考答案
def is_palindrome(s):
    # 去除非字母数字字符并转为小写
    cleaned = ''.join(c.lower() for c in s if c.isalnum())
    return cleaned == cleaned[::-1]
 
# 测试
test_strings = ["A man a plan a canal Panama", "Hello", "racecar", "12321"]
for s in test_strings:
    print(f"'{s}' -> {is_palindrome(s)}")

本章小结

本章学习了Python的控制流语句:

掌握控制流后,你可以编写具有复杂逻辑的Python程序了。下一章将学习函数,让代码更加模块化和可重用。

进一步阅读