从zer0开始学Python|Day 08:深入理解Python中的迭代器与生成器,区别、实现与实战应用
Python迭代器与生成器对比指南 摘要:本文系统介绍了Python中迭代器与生成器的核心概念与应用。迭代器是通过实现__iter__()和__next__()方法的对象,适合自定义遍历逻辑;生成器则是使用yield实现的特殊迭代器,具有惰性求值特性。关键区别在于:迭代器需要手动维护状态,生成器自动保存执行状态;迭代器适合精细控制,生成器更简洁高效,特别适合处理大数据流和文件读取。文中提供了数字范
目录
前言
在 Python 开发中,我们经常和 “遍历” 打交道 —— 从列表里取数据、从文件里读内容、从数据库里捞记录。迭代器和生成器就是帮我们高效做这件事的 “工具人”。但很多人总把它俩搞混:有人觉得生成器就是迭代器,有人用迭代器时总担心内存爆炸,有人写生成器时不知道 yield 到底咋用。
一、迭代器
1、迭代器的基本概念
在 Python 中,迭代器(Iterator) 是一种可以记住遍历位置的对象。它必须实现两个方法:
-
__iter__()
:返回迭代器对象本身; -
__next__()
:返回容器中的下一个元素,如果没有更多元素则抛出StopIteration
异常。
所有可迭代对象(如列表、元组、字典等)都可以通过 iter()
函数转换为迭代器。
示例:获取并使用内置迭代器
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
2、迭代器的实现方式
我们可以通过自定义类来手动实现一个迭代器,只需要实现 __iter__()
和 __next__()
方法即可。
示例:实现一个数字范围迭代器
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
num = self.current
self.current += 1
return num
else:
raise StopIteration
# 使用自定义迭代器
for i in MyRange(1, 5):
print(i)
# 输出:
# 1
# 2
# 3
# 4
3、迭代器的典型应用场景
-
遍历集合数据结构(如列表、元组、字典);
-
实现自定义的数据访问逻辑;
-
在需要精细控制遍历过程时使用;
-
作为某些标准库函数或框架的接口规范;
示例:模拟数据库查询结果迭代器
假设我们有一个模拟的数据库查询结果,希望以迭代器的方式一行一行返回数据。
class DBResultIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
# 模拟数据库查询结果
data = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}, {"id": 3, "name": "Charlie"}]
db_iter = DBResultIterator(data)
for row in db_iter:
print(row)
输出:
{'id': 1, 'name': 'Alice'}
{'id': 2, 'name': 'Bob'}
{'id': 3, 'name': 'Charlie'}
二、生成器
1、生成器的基本概念
生成器(Generator) 是一种特殊的迭代器,它通过函数配合 yield
关键字实现。每次调用 next()
时,生成器会从上次暂停的地方继续执行。生成器的最大优势是 惰性求值 ,即只在需要的时候才生成值,节省内存资源。
示例:简单的生成器函数
def my_generator():
yield "Hello"
yield "World"
yield "!"
gen = my_generator()
print(next(gen)) # 输出: Hello
print(next(gen)) # 输出: World
print(next(gen)) # 输出: !
2、生成器的实现方式
生成器有两种常见实现方式:
-
生成器函数(带 yield 的函数)
-
生成器表达式(类似列表推导式,但使用圆括号)
示例一:生成器函数 —— 斐波那契数列
def fibonacci(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
# 使用生成器
for num in fibonacci(100):
print(num)
示例二:生成器表达式
squares_gen = (x * x for x in range(5))
print(next(squares_gen)) # 输出: 0
print(next(squares_gen)) # 输出: 1
print(next(squares_gen)) # 输出: 4
3、生成器的典型应用场景
-
处理大数据流或无限序列;
-
延迟加载数据,提升性能;
-
构建简洁高效的迭代逻辑;
-
实现协程或异步编程的基础组件;
示例:模拟传感器数据流
在物联网或 实时监控 系统中,我们可能需要不断获取传感器数据。由于这些数据是持续产生的,使用生成器非常适合。
import random
import time
def sensor_data_stream():
while True:
yield random.randint(20, 30) # 模拟温度数据
time.sleep(1) # 每秒产生一次数据
# 使用生成器模拟实时数据流
for temp in sensor_data_stream():
print(f"当前温度: {temp}°C")
4、读取大文件
当处理非常大的日志文件时,一次性读入内存会导致程序崩溃,这时生成器就派上用场了!
示例:用生成器逐行读取文件
def read_large_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
yield line.strip()
# 使用生成器逐行处理
for line in read_large_file('big_log.txt'):
print(line) # 或者进行其他处理
三、迭代器与生成器的核心区别
特性 | 迭代器 | 生成器 |
---|---|---|
实现方式 |
类中定义 |
使用 |
状态维护 |
手动维护状态 |
自动保存执行状态 |
可重用性 |
一般不可重置 |
不可重置,除非重新创建 |
编写难度 |
较复杂 |
更加简洁 |
内存占用 |
占用常规内存 |
惰性计算,节省内存 |
-
迭代器是 “手动挡”:需要自己控制状态和迭代逻辑,适合自定义容器。
-
生成器是 “自动挡”:用 yield 自动处理迭代,代码更简洁,适合大数据和动态序列。
总结:
迭代器和生成器就像是两种不同的工具,各有各的用途。迭代器适合做精细控制,而生成器则是“懒人福音”,尤其是在处理大数据时特别省心。不管是迭代器还是生成器,核心都是 “惰性计算” 和 “高效遍历”。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)