目录

第五章:循环语句

本章目标

完成本章学习后,你将能够:

for循环

基本语法

# 遍历列表
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
 
# 遍历字符串
for char in "Hello":
    print(char)  # H, e, l, l, o
 
# 遍历字典
game = {"name": "Minecraft", "year": 2011, "platform": "Multi"}
for key in game:
    print(f"{key}: {game[key]}")
 
# 遍历字典项
for key, value in game.items():
    print(f"{key} = {value}")

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(2, 6):
    print(i)  # 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
 
# range生成的是惰性序列
print(range(5))        # range(0, 5)
print(list(range(5)))  # [0, 1, 2, 3, 4]

enumerate()函数

需要同时获取索引和值时:

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

zip()函数

同时遍历多个序列:

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["NYC", "LA", "SF"]
 
# 并行遍历
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}岁, 来自{city}")
 
# zip以最短序列为准
short = [1, 2]
long = ["a", "b", "c", "d"]
for s, l in zip(short, long):
    print(s, l)  # 1 a, 2 b
 
# zip_longest(填充缺失值)
from itertools import zip_longest
for s, l in zip_longest(short, long, fillvalue="-"):
    print(s, l)  # 1 a, 2 b, - c, - d

while循环

基本语法

# 基本while
count = 0
while count < 5:
    print(count)
    count += 1
 
# 用户输入验证
while True:
    password = input("请输入密码(至少6位):")
    if len(password) >= 6:
        print("密码设置成功")
        break
    print("密码太短,请重试")

while与else

# while-else:循环正常结束时执行else
def is_prime(n):
    if n < 2:
        return False
    i = 2
    while i * i <= n:
        if n % i == 0:
            print(f"{n} = {i} × {n//i}")
            break
        i += 1
    else:
        # 循环没有被break,说明是素数
        print(f"{n} 是素数")
        return True
    return False
 
is_prime(17)  # 17 是素数
is_prime(18)  # 18 = 2 × 9

循环控制语句

break语句

# 查找第一个偶数
numbers = [1, 3, 5, 8, 9, 10]
for num in numbers:
    if num % 2 == 0:
        print(f"找到偶数: {num}")
        break
else:
    print("没有找到偶数")

continue语句

# 跳过奇数,只处理偶数
for i in range(10):
    if i % 2 != 0:
        continue
    print(f"偶数: {i}")  # 0, 2, 4, 6, 8
 
# 处理数据时跳过无效项
data = [1, None, 2, "invalid", 3, None, 4]
total = 0
for item in data:
    if not isinstance(item, (int, float)):
        continue
    total += item
print(f"总和: {total}")  # 10

pass语句

# pass是空操作,用于占位
for i in range(10):
    if i % 2 == 0:
        pass  # TODO: 处理偶数
    else:
        print(f"奇数: {i}")
 
# 空类/函数定义
class MyClass:
    pass  # 稍后实现
 
def my_function():
    pass  # 稍后实现

嵌套循环

# 打印乘法表
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f"{j}×{i}={i*j}", end="\t")
    print()
 
# 遍历二维列表
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
 
for row in matrix:
    for item in row:
        print(item, end=" ")
    print()
 
# 带条件的嵌套循环
for i in range(2, 100):
    is_prime = True
    for j in range(2, int(i**0.5) + 1):
        if i % j == 0:
            is_prime = False
            break
    if is_prime:
        print(i, end=" ")  # 打印2到99的素数

迭代器详解

迭代器协议

# 可迭代对象(Iterable):实现了__iter__()
# 迭代器(Iterator):实现了__iter__()和__next__()
 
# 获取迭代器
numbers = [1, 2, 3]
iterator = iter(numbers)
 
print(next(iterator))  # 1
print(next(iterator))  # 2
print(next(iterator))  # 3
# print(next(iterator))  # StopIteration异常
 
# 手动遍历
iterator = iter(numbers)
while True:
    try:
        item = next(iterator)
        print(item)
    except StopIteration:
        break

自定义迭代器

class CountDown:
    def __init__(self, start):
        self.start = start
 
    def __iter__(self):
        return self
 
    def __next__(self):
        if self.start <= 0:
            raise StopIteration
        num = self.start
        self.start -= 1
        return num
 
# 使用
for num in CountDown(5):
    print(num)  # 5, 4, 3, 2, 1

循环最佳实践

1. 使用for代替while遍历序列

# 不推荐
i = 0
while i < len(items):
    print(items[i])
    i += 1
 
# 推荐
for item in items:
    print(item)

2. 使用enumerate获取索引

# 不推荐
for i in range(len(items)):
    print(f"{i}: {items[i]}")
 
# 推荐
for i, item in enumerate(items):
    print(f"{i}: {item}")

3. 使用zip并行遍历

# 不推荐
for i in range(len(names)):
    print(f"{names[i]}: {ages[i]}")
 
# 推荐
for name, age in zip(names, ages):
    print(f"{name}: {age}")

4. 使用in成员检查

# 不推荐
found = False
for item in items:
    if item == target:
        found = True
        break
 
# 推荐
found = target in items

本章练习

1. 九九乘法表:使用嵌套循环打印完整的九九乘法表 2. 素数筛选:实现埃拉托斯特尼筛法,找出100以内的所有素数 3. 列表扁平化:将嵌套列表1,2,3],[4,5],[6扁平化为[1,2,3,4,5,6] 4. 矩阵转置:将矩阵进行转置操作 5. 猜数字游戏:程序随机生成1-100的数字,用户猜测直到猜中

本章小结

本章我们学习了:

下一章:第六章:推导式与生成器表达式