本文目录导读:

- 目录导读
- 迭代器基础概念
- Python迭代器协议:底层机制剖析
- 遍历常用数据结构的实际案例
- 自定义迭代器案例:斐波那契数列生成器
- 生成器:更优雅的迭代器实现
- 实际场景应用:迭代器如何解决真问题?
- 性能对比与最佳实践
Python迭代器遍历实战:从基础语法到高级案例的完整指南
目录导读
- 迭代器基础概念 – 什么是迭代器?为什么需要它?
- Python迭代器协议 –
__iter__()与__next__()的底层机制 - 遍历常用数据结构 – 列表、字典、文件的行级遍历
- 自定义迭代器案例 – 用类实现斐波那契数列生成器
- 生成器简化迭代 –
yield关键字的魔力 - 实际场景应用 – 大文件拆分、实时数据流处理
- 性能对比与最佳实践 – 迭代器 vs 列表推导式 vs 循环
迭代器基础概念
Q:迭代器(Iterator)和可迭代对象(Iterable)有什么区别?
A:可迭代对象是实现了 __iter__() 方法的对象(如列表、元组、字典),而迭代器是实现了 __iter__() 和 __next__() 的对象,迭代器可以通过 next() 逐个返回元素,直到抛出 StopIteration 异常。
核心点:迭代器的本质是“惰性求值”——只在需要时产生下一个值,不一次性加载所有数据到内存,这对处理大文件、无限序列(如斐波那契数列)至关重要。
Python迭代器协议:底层机制剖析
Python中任何对象,只要实现了以下两个方法,就是迭代器:
__iter__():返回迭代器自身(通常返回self)。__next__():返回下一个可用的元素;如果没有更多元素,则抛出StopIteration。
示例:手动模拟列表遍历
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 循环底层就是自动调用 iter() 和 next(),并捕获 StopIteration 异常。
遍历常用数据结构的实际案例
1 列表遍历
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
print(fruit.upper())
输出:APPLE BANANA CHERRY
2 字典遍历(键、值、键值对)
student_scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92}
for name, score in student_scores.items():
print(f'{name}: {score}')
3 文件行级遍历(处理大文件核心方法)
with open('large_log.txt', 'r') as file:
for line in file: # file 本身是可迭代对象
if 'ERROR' in line:
print(line.strip())
说明:文件对象实现的是行级迭代器,逐行读取内存,适合处理GB级日志文件。
自定义迭代器案例:斐波那契数列生成器
需求:生成前 N 个斐波那契数,但不预先生成整个列表(避免内存爆炸)。
class FibonacciIterator:
def __init__(self, max_count):
self.max_count = max_count
self.count = 0
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
if self.count >= self.max_count:
raise StopIteration
self.count += 1
self.a, self.b = self.b, self.a + self.b
return self.a
# 使用
fib = FibonacciIterator(10)
for num in fib:
print(num, end=' ') # 输出:1 1 2 3 5 8 13 21 34 55
Q:为什么不直接用列表存储?
A:如果只关心前几个值,列表浪费内存,迭代器只存储当前状态(a, b, count),适合无限序列或超长序列。
生成器:更优雅的迭代器实现
生成器是用 yield 关键字的函数,Python自动创建迭代器对象,无需手动实现 __iter__ 和 __next__。
生成器版斐波那契:
def fibonacci_gen(max_count):
a, b = 0, 1
for _ in range(max_count):
a, b = b, a + b
yield a
for num in fibonacci_gen(10):
print(num, end=' ') # 输出相同结果
优点:代码更简洁,状态自动保存。yield 每次暂停函数,下次从暂停处继续。
实际案例:分块读取大文件
def read_in_chunks(file_path, chunk_size=1024):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
# 使用
for chunk in read_in_chunks('big_video.mp4'):
process_chunk(chunk) # 模拟处理每1KB数据
实际场景应用:迭代器如何解决真问题?
1 实时数据流处理(传感器数据)
import random
import time
def sensor_data_stream():
"""模拟无限传感器读数流"""
while True:
yield {'temperature': random.uniform(20, 30),
'humidity': random.uniform(40, 60)}
# 只取前5个有效数据
stream = sensor_data_stream()
for i, data in enumerate(stream):
if data['temperature'] > 25:
print(f"Alert: High temp {data['temperature']:.1f}°C")
if i >= 100: # 处理100条后停止
break
价值:不需要存储所有传感器数据,边产生边处理,内存恒定。
2 数据库查询分页(SQLAlchemy示例)
def paginate_query(model, page_size=50):
page = 1
while True:
results = model.query.paginate(page, page_size, error_out=False).items
if not results:
break
yield from results # 生成器委托
page += 1
# 遍历所有用户表记录(可能百万级)
for user in paginate_query(User):
print(user.email)
注意:yield from 可将子生成器元素依次产出,简化迭代器嵌套。
性能对比与最佳实践
1 速度测试:迭代器 vs 列表推导式
import time
# 方法1:列表推导式(立即生成所有元素)
start = time.time()
squares = [x**2 for x in range(1000000)]
print(f"列表推导式: {time.time()-start:.3f}秒")
# 方法2:生成器推导式(惰性)
start = time.time()
gen = (x**2 for x in range(1000000))
list(gen) # 强制求值
print(f"生成器: {time.time()-start:.3f}秒")
结果说明:两者速度相近,但列表占用内存约 8MB(100万个整数),生成器仅约 200 字节。
2 选择指南
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 小数据集(<1万) | 列表/元组 | 代码可读性高 |
| 中等数据(1万-100万) | 列表推导式 | 速度略优 |
| 大数据集(>100万) | 迭代器/生成器 | 内存友好 |
| 无限序列(如实时数据) | 生成器 | 只在需要时产出 |
| 需要多次遍历 | 转换为列表 | 迭代器只能遍历一次 |
Q1:如何判断一个对象是否可迭代?
from collections.abc import Iterable print(isinstance([1,2], Iterable)) # True print(isinstance(123, Iterable)) # False
Q2:迭代器能遍历多次吗?
A:不能,迭代器是一次性消耗品,用完即止,如需多次遍历,用 list(iterator) 转为列表,或用 itertools.tee() 复制。
Q3:for 循环和 while 手动调用 next() 哪个更好?
A:通常用 for,它自动处理边界和异常,只有在需要手动控制步长或条件时(如跳过元素),才用 while+next()。
Q4:生成器推导式与列表推导式有什么区别?
A:列表推导式用 ,生成器推导式用 ,前者立刻生成完整列表,后者返回生成器对象,只在迭代时计算。
迭代器是Python函数式编程和高效数据处理的基石,从基础文件遍历到自定义无限序列生成器,掌握它意味着你能用最少的资源处理最多数据,对于任何涉及大数据、实时流或内存敏感的应用,迭代器都是必杀器,建议读者亲手实现一个自定义迭代器(如素数生成器),并对比与列表存储的性能差异,这将极大加深理解。
(全文完)
综合自Python官方文档、Real Python、GeeksforGeeks、Stack Overflow等权威来源,结合实战场景重组创作。*