当前位置: 首页 > news >正文

【Python】迭代器(Iterator)vs 生成器(Generator)

迭代器(Iterator) vs 生成器(Generator)

  • 1.迭代器(Iterator)
    • 1.1 是什么?
    • 1.2 示例
    • 1.3 适用场景
  • 2.生成器(Generator)
    • 2.1 是什么?
    • 2.2 示例
    • 2.3 适用场景
  • 3.迭代器 vs 生成器
  • 4.如何选择?
  • 5.经典例子
    • 5.1 读取大文件(生成器更优)
    • 5.2 自定义树遍历(迭代器更优)
  • 6.总结

1.迭代器(Iterator)

1.1 是什么?

  • 迭代器是一个 可以逐个访问元素的对象,比如 listdictset 都可以通过 iter() 转换成迭代器。
  • 它必须实现 __iter__()__next__() 方法。
  • 特点
    • 只能前进,不能后退。
    • 遍历结束后,再调用 next() 会抛出 StopIteration 错误。

1.2 示例

my_list = [1, 2, 3]
it = iter(my_list)  # 转换成迭代器print(next(it))  # 输出 1
print(next(it))  # 输出 2
print(next(it))  # 输出 3
print(next(it))  # 抛出 StopIteration

1.3 适用场景

  • 大数据遍历(如逐行读取大文件,避免内存爆炸)。
  • 自定义遍历逻辑(如树的深度优先遍历,就像《迭代器与生成器(一)》中的 DepthFirstIterator)。

2.生成器(Generator)

2.1 是什么?

  • 生成器是一种 特殊的迭代器,用 yield 关键字定义。
  • 特点
    • 惰性计算(需要时才计算,节省内存)。
    • 代码更简洁,不用手动实现 __iter____next__
    • 可以用 for 循环直接遍历。

2.2 示例

def count_up_to(n):i = 1while i <= n:yield i  # 每次 next() 调用时返回 i,并暂停在这里i += 1gen = count_up_to(3)  # 返回生成器对象print(next(gen))  # 输出 1
print(next(gen))  # 输出 2
print(next(gen))  # 输出 3
print(next(gen))  # 抛出 StopIteration# 也可以用 for 循环
for num in count_up_to(3):print(num)  # 输出 1, 2, 3

2.3 适用场景

  • 处理大数据流(如逐行读取日志文件)。
  • 无限序列(如斐波那契数列)。
  • 协程(Coroutine)(结合 yield 实现异步编程)。

3.迭代器 vs 生成器

特性迭代器(Iterator)生成器(Generator)
定义方式需要实现 __iter____next__yield 定义函数
内存占用可能占用较大内存(如 list惰性计算,省内存
代码简洁度较复杂(需手动实现)更简洁
适用场景自定义遍历逻辑惰性计算、无限序列、协程

4.如何选择?

  • 用迭代器
    • 需要自定义遍历逻辑(如树、图的遍历)。
    • 需要更底层的控制(如手动调用 next())。
  • 用生成器
    • 需要 惰性计算(如处理大文件、无限序列)。
    • 代码要更简洁(避免手动实现 __next__)。

5.经典例子

5.1 读取大文件(生成器更优)

def read_large_file(file_path):with open(file_path, "r") as f:for line in f:yield line  # 逐行读取,不占内存for line in read_large_file("huge_log.txt"):print(line)

生成器更合适,因为文件可能很大,直接 read() 会爆内存。

5.2 自定义树遍历(迭代器更优)

class Tree:def __init__(self, value):self.value = valueself.children = []def __iter__(self):return DepthFirstIterator(self)  # 自定义迭代器

迭代器更合适,因为需要控制遍历顺序(如深度优先、广度优先)。

6.总结

  • 迭代器:适合 自定义遍历逻辑(如树、图)。
  • 生成器:适合 惰性计算(如大文件、无限序列)。
  • 生成器是迭代器的“语法糖”,能用生成器的地方尽量用生成器,代码更简洁!

希望本文能让你搞懂迭代器和生成器!🚀

相关文章:

  • 十倍开发效率 - IDEA插件之 Mybatis Log Free
  • 最新论文 | SegEarth-R1: 遥感+推理大模型!Geospatial Pixel Reasoning
  • 四月十六日华为发布会
  • 使用原生button封装一个通用按钮组件
  • 2021-11-09 C++三位数平方含有该数
  • 【数据分析实战】使用 Matplotlib 绘制直方图
  • 面向对象—有理数类的设计
  • 【软考-系统架构设计师】设计模式三大类型解析
  • Linux :进程替换
  • 模型加载常见问题
  • vue3 element-plus中的国际化在onMounted中的写法
  • 【Java学习笔记】位运算
  • vos3000外呼系统怎么给普通用户开通播放下载录音权限?
  • CSS 字体背景波浪
  • Linux操作系统--静态库和动态库的生成and四种解决加载找不到动态库的四种方法
  • 【2025最新版】火鸟门户v8.5系统源码+PC、H5、小程序 +数据化大屏插件
  • 健康养生指南
  • CMake Error at build/_deps/glog-src/CMakeLists.txt:1 (cmake_minimum_required):
  • MCP和A2A是什么?
  • Android利用MediaCodec和GLSurfaceView录制视频
  • 巴菲特谈卸任CEO:开始偶尔失去平衡,但仍然保持敏锐的头脑,仍打算继续工作
  • 重庆市委原常委、政法委原书记陆克华被决定逮捕
  • 广州一饮品店取名“警茶”?市监局:取名没问题,但图像会产生误解
  • 科创板年内第3家!健信超导IPO获受理,拟募资8.65亿
  • 《淮水竹亭》:一手好牌,为何打成这样
  • 印度一战机在巴基斯坦旁遮普省被击落,飞行员被俘