Python迭代器和生成器的核心价值在于按需产生数据,避免一次性加载全部内容到内存;迭代器通过__iter__()和__next__()实现单向遍历,生成器以yield简化创建,适用于大文件、数据库游标及无限序列等场景。

Python迭代器和生成器的核心价值,在于按需产生数据,避免一次性加载全部内容到内存。尤其处理大文件、海量数据或无限序列时,能显著降低内存占用。
什么是迭代器(Iterator)
迭代器是实现了__iter__()和__next__()方法的对象,每次调用next()返回一个元素,直到抛出StopIteration异常。内置容器如list、tuple、str等都可被iter()转为迭代器。
- 手动创建迭代器:继承object,实现两个魔法方法;适合封装自定义遍历逻辑(如树的中序遍历)
- 用iter(obj)获取迭代器后,只能单向遍历一次;再次遍历需重新创建
- for循环底层就是调用iter()和next(),所以支持迭代器的对象天然支持for
生成器(Generator):更简洁的迭代器写法
生成器函数使用yield关键字,调用时返回一个生成器对象(即迭代器),不执行函数体;每次next()才运行到下一个yield并暂停,保存上下文。
- 比手动写迭代器类代码更少、更直观;适合简单数据流逻辑(如逐行读大文件、计算斐波那契)
- 生成器表达式(x*2 for x in range(1000000))比列表推导式[x*2 for x in range(1000000)]省内存——前者返回迭代器,后者直接生成百万个整数存入内存
- 生成器不可重用:一旦遍历完就耗尽,需重新调用函数获得新生成器
实际节省内存的典型场景
不是所有情况都需要生成器,但以下场景效果明显:
立即学习“Python免费学习笔记(深入)”;
- 读取超大文本文件:用for line in open('big.log')(文件对象本身就是迭代器),而不是open('big.log').readlines()把全部行载入内存
- 处理数据库游标结果集:用cursor.fetchall()会加载全部记录;而for row in cursor(若驱动支持)是逐条获取,内存恒定
- 生成无限序列:如素数生成器、时间戳流、随机数据流,只能用生成器(或迭代器),否则根本无法“完成”构造
注意陷阱与优化提示
生成器虽好,但误用反而影响可读性或性能:
- 小数据量(如几十个元素)用列表更高效——生成器有额外的函数调用和状态维护开销
- 需要多次遍历?生成器不行,得转成list或用itertools.tee()复制迭代器(注意:复制后首次遍历仍会消耗原迭代器)
- 调试生成器内部逻辑较难,可用print()加yield,或改用普通函数+return先验证逻辑再改写










