Python迭代器与生成器:优雅的惰性计算艺术

一、迭代器协议:__iter____next__的魔法

迭代器的本质

Python中的迭代器不是存储所有元素的容器,而是惰性计算的协议实现。核心在于两个方法:

  • __iter__():返回迭代器自身
  • __next__():返回下一个元素,耗尽时抛出StopIteration
python 复制代码
class CountDown:
    """自定义迭代器:倒计时"""
    def __init__(self, start):
        self.current = start
    
    def __iter__(self):
        return self  # 迭代器必须返回自身
    
    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        num = self.current
        self.current -= 1
        return num

# 使用
for num in CountDown(5):
    print(num)  # 输出: 5 4 3 2 1

迭代器的优势

  • 内存高效:不一次性加载所有数据
  • 无限序列:可以表示无限长的序列
  • 通用接口 :统一的for循环处理方式

二、生成器:yield的暂停与恢复魔法

生成器函数

生成器是创建迭代器的语法糖 ,使用yield暂停函数执行并返回值:

python 复制代码
def fibonacci_generator(limit):
    """生成斐波那契数列"""
    a, b = 0, 1
    count = 0
    while count < limit:
        yield a  # 暂停执行,返回a
        a, b = b, a + b
        count += 1

# 生成器对象
fib_gen = fibonacci_generator(10)
print(next(fib_gen))  # 0
print(next(fib_gen))  # 1
print(list(fib_gen))  # [1, 2, 3, 5, 8, 13, 21, 34]

生成器表达式

更简洁的生成器创建方式:

python 复制代码
# 传统列表推导(立即计算)
squares_list = [x**2 for x in range(1000000)]  # 占用大量内存

# 生成器表达式(惰性计算)
squares_gen = (x**2 for x in range(1000000))  # 几乎不占内存
print(next(squares_gen))  # 0
print(next(squares_gen))  # 1

三、yield from:生成器的委派机制

简化嵌套生成器

python 复制代码
def chain_generators(*iterables):
    """连接多个可迭代对象"""
    for iterable in iterables:
        yield from iterable  # 委派给子生成器

# 等效于:
# for item in iterable:
#     yield item

result = list(chain_generators([1, 2], 'ab', (True, False)))
# [1, 2, 'a', 'b', True, False]

四、生成器的高级用法

1. 协程:双向通信

python 复制代码
def coroutine_generator():
    """接收外部数据的生成器"""
    total = 0
    while True:
        value = yield total  # 暂停并接收发送的值
        if value is None:
            break
        total += value

coro = coroutine_generator()
next(coro)  # 启动生成器(预激)
print(coro.send(10))  # 10
print(coro.send(20))  # 30
coro.close()  # 关闭生成器

2. 上下文管理

python 复制代码
from contextlib import contextmanager

@contextmanager
def managed_resource():
    """生成器实现的上下文管理器"""
    print("获取资源")
    resource = "资源对象"
    try:
        yield resource
    finally:
        print("释放资源")

with managed_resource() as r:
    print(f"使用 {r}")

五、性能对比:迭代器 vs 列表

python 复制代码
import time
import sys

def test_memory_usage():
    """内存使用对比"""
    # 列表:一次性加载所有数据
    list_data = [i for i in range(1000000)]
    print(f"列表内存: {sys.getsizeof(list_data):,} bytes")
    
    # 生成器:惰性计算
    gen_data = (i for i in range(1000000))
    print(f"生成器内存: {sys.getsizeof(gen_data):,} bytes")

def test_performance():
    """性能对比"""
    n = 10_000_000
    
    # 列表推导
    start = time.time()
    _ = [x**2 for x in range(n)]
    list_time = time.time() - start
    
    # 生成器表达式
    start = time.time()
    _ = (x**2 for x in range(n))
    gen_time = time.time() - start
    
    print(f"列表推导: {list_time:.3f}s")
    print(f"生成器表达式: {gen_time:.3f}s")

test_memory_usage()
test_performance()

六、实用模式与陷阱

1. 生成器的一次性使用

python 复制代码
gen = (x for x in range(3))
print(list(gen))  # [0, 1, 2]
print(list(gen))  # [] !已耗尽

2. itertools模块的迭代器工具

python 复制代码
from itertools import islice, count, cycle

# 无限序列的切片
first_10 = list(islice(count(10), 5))  # [10, 11, 12, 13, 14]

# 循环迭代器
cycler = cycle('ABC')
print([next(cycler) for _ in range(6)])  # ['A', 'B', 'C', 'A', 'B', 'C']

3. 自定义可迭代对象

python 复制代码
class BatchProcessor:
    """分批处理大数据集"""
    def __init__(self, data, batch_size):
        self.data = data
        self.batch_size = batch_size
    
    def __iter__(self):
        """返回生成器迭代器"""
        for i in range(0, len(self.data), self.batch_size):
            yield self.data[i:i + self.batch_size]

data = list(range(100))
batcher = BatchProcessor(data, 10)
for batch in batcher:
    process(batch)  # 每次处理10个元素

总结

迭代器和生成器是Python惰性计算哲学的体现,它们通过:

  1. 按需计算节省内存
  2. 统一的迭代协议简化API设计
  3. 生成器协程实现复杂控制流
  4. 优雅的语法让代码更清晰
相关推荐
亿牛云爬虫专家3 小时前
Worker越简单,系统越稳定:从单机到集群
爬虫·python·集群·爬虫代理·单机·代理ip·worker
smj2302_796826524 小时前
解决leetcode第3801题合并有序列表的最小成本
数据结构·python·算法·leetcode
AI数据皮皮侠4 小时前
中国乡村旅游重点村镇数据
大数据·人工智能·python·深度学习·机器学习
小北方城市网4 小时前
第 11 课:Python 全栈项目进阶与职业发展指南|从项目到职场的无缝衔接(课程终章・进阶篇)
大数据·开发语言·人工智能·python·数据库架构·geo
danyang_Q4 小时前
d2l安装(miniforge+cuda+pytorch)
人工智能·pytorch·python
源码梦想家5 小时前
多语言高性能异步任务队列与实时监控实践:Python、Java、Go、C++实战解析
开发语言·python
百***78755 小时前
Gemini 3.0 Pro与2.5深度对比:技术升级与开发实战指南
开发语言·python·gpt
reasonsummer5 小时前
【教学类-122-01】20260105“折纸-东南西北中”(4个方向文字,9个小图案)
python·通义万相
智航GIS5 小时前
9.6 JSON 基本操作
python·json
@zulnger6 小时前
python 学习笔记(文件读写)
笔记·python·学习