Skip to content

Python 3 - 循环

通常,Python 代码按照从第一条语句到最后一条语句的顺序依次执行。然而,你经常需要重复执行一段代码多次,或者根据特定条件执行代码。控制流(Control flow)结构允许更复杂的执行路径。

循环语句(Loop statements)提供了一种重复执行代码块(block of code)的方式。这对于处理集合中的项目、重复计算或等待事件等任务至关重要。

Python 提供了两种主要的循环构造:

循环类型描述
while 循环只要给定条件(condition)保持 True(真),就重复执行代码块。条件在每次迭代(iteration)之前检查。
for 循环迭代遍历任何序列(sequence)(如列表 list、元组 tuple、字符串 string 或范围 range)或其他可迭代对象(iterable object)的项目,对每个项目执行一次代码块。

此外,循环可以被嵌套(nested),这意味着你可以在一个循环内部放置另一个循环,以处理更复杂的迭代模式(例如,遍历网格中的行和列)。

while 循环重复执行目标语句(statement(s)),只要给定的布尔条件(Boolean condition)为真。

while condition:
# 当 condition 为 True 时执行的代码块
statement(s)
# 循环结束后(condition 变为 False)执行这里的代码

示例:从 1 数到 5

#!/usr/bin/env python3
count = 1
while count <= 5:
print(f"Count is: {count}")
count += 1 # 重要:更新条件中使用的变量!
print("Loop finished!")

输出:

Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Loop finished!

警告:确保条件最终变为 False,否则你会创建一个无限循环(infinite loop)。

for 循环迭代遍历序列(或其他可迭代对象)中的项目。当你事先知道需要循环多少次,或者想处理集合中的每一个项目时,它通常比 while 循环更方便。

for item in iterable:
# 对每个 item 执行的代码块
statement(s)
# 在循环遍历完所有项目后执行这里的代码

示例:遍历列表

#!/usr/bin/env python3
fruits = ["apple", "banana", "cherry"]
print("Available fruits:")
for fruit in fruits:
print(f"- {fruit.capitalize()}")
print("Loop finished!")

输出:

Available fruits:
- Apple
- Banana
- Cherry
Loop finished!

示例:使用 range()

range() 函数生成一个数字序列,常用于 for 循环。

#!/usr/bin/env python3
# 循环 5 次 (0 到 4)
print("Looping with range(5):")
for i in range(5):
print(f"Iteration {i}")
# 从 2 循环到 6 (不包括 6)
print("\nLooping with range(2, 6):")
for i in range(2, 6):
print(f"Iteration {i}")
# 从 1 循环到 10,步长为 2
print("\nLooping with range(1, 10, 2):")
for i in range(1, 10, 2):
print(f"Iteration {i}")

输出:

Looping with range(5):
Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Looping with range(2, 6):
Iteration 2
Iteration 3
Iteration 4
Iteration 5
Looping with range(1, 10, 2):
Iteration 1
Iteration 3
Iteration 5
Iteration 7
Iteration 9

循环控制语句改变循环内部的正常执行流程:

语句描述
break提前终止当前循环。执行会继续到循环之后的第一条语句。
continue跳过当前迭代的剩余部分,并继续进行循环的下一次迭代。
pass不执行任何操作。在语法要求有语句但无需执行任何动作的地方充当占位符(例如,在空循环或函数体中)。

使用 break 和 continue 的示例:

#!/usr/bin/env python3
numbers = [1, 2, 3, -4, 5, 6, -7, 8]
print("Processing numbers:")
for num in numbers:
if num < 0:
print(f"Found negative number {num}, stopping.")
break # 退出循环
if num % 2 == 0:
print(f"Skipping even number {num}.")
continue # 跳到下一个数字
print(f"Processing odd number {num}.")
print("Loop finished or broken.")

输出:

Processing numbers:
Processing odd number 1.
Skipping even number 2.
Processing odd number 3.
Found negative number -4, stopping.
Loop finished or broken.

Python 循环(for 和 while)可以有一个可选的 else 块。else 块中的代码仅在循环完成其迭代,且没有遇到 break 语句时执行。

#!/usr/bin/env python3
my_list = [1, 3, 5, 7]
search_value = 6
for item in my_list:
if item == search_value:
print(f"Found {search_value}!")
break
else:
# 仅在循环正常完成时执行 (没有 break)
print(f"{search_value} not found in the list.")
search_value = 5
for item in my_list:
if item == search_value:
print(f"Found {search_value}!")
break
else:
print(f"{search_value} not found in the list.") # 这不会运行

输出:

6 not found in the list.
Found 5!

底层上,for 循环与迭代器(iterators)一起工作。迭代器是一个允许一次遍历一个集合(如列表或字符串)中元素的特定对象。它实现了迭代器协议(iterator protocol),该协议要求有 __iter__() 方法(返回迭代器对象本身)和 __next__() 方法(返回下一个项目,或者在遍历完时抛出 StopIteration 异常)。

你可以使用内置的 iter() 函数从任何可迭代对象创建迭代器,并使用 next() 获取项目:

#!/usr/bin/env python3
my_list = [10, 20, 30]
it = iter(my_list) # 获取一个迭代器
print(next(it)) # 输出: 10
print(next(it)) # 输出: 20
print(next(it)) # 输出: 30
# print(next(it)) # 这会抛出 StopIteration 异常
# for 循环会自动处理这种情况:
print("\nUsing a for loop:")
for x in my_list: # 隐式使用迭代器
print(x)

生成器(generator)是创建迭代器的一种更简单的方式。它的定义类似于普通函数,但使用 yield 关键字一次返回一个值。当调用生成器函数时,它返回一个生成器对象(一种迭代器)。函数的执行会在 yield 处暂停,并在下次调用 next() 时从同一点恢复。

示例:斐波那契数列生成器

#!/usr/bin/env python3
def fibonacci_generator(limit):
"""生成小于指定 limit 的斐波那契数列。"""
a, b = 0, 1
while a < limit:
yield a
a, b = b, a + b
# 获取生成器对象
fib_gen = fibonacci_generator(50)
print("Fibonacci numbers < 50:")
# 使用 for 循环遍历生成器
for num in fib_gen:
print(num, end=" ") # 输出: 0 1 1 2 3 5 8 13 21 34
print()

生成器对于处理大型序列非常节省内存,因为它们按需生成项目,而不是将整个序列存储在内存中。