Python中迭代器和生成器让数据“懒”得刚刚好

 更新时间:2026年03月13日 10:19:19   作者:南风以南  
本文介绍了Python中的迭代器和生成器,它们是实现延迟计算的实用工具,只在需要时才计算,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

“聪明的程序员不是算得更快,而是算得更少。”
—— 迭代器与生成器,正是 Python 践行这一哲学的优雅体现。

问题引入

你有没有遇到过这样的场景?

  • 想遍历一个超大文件,但内存爆了 ❌
  • 写了个 range(10**9),结果电脑卡死 🐌
  • 面试被问:“迭代器和生成器有啥区别?” 瞬间语塞 😅

别慌!今天我们就把这两个看似高冷的概念,用一杯咖啡的时间讲清楚 ☕️。它们不是魔法,而是延迟计算(Lazy Evaluation) 的实用工具——只在你需要时才干活,绝不提前内卷!

核心剖析

迭代器(Iterator):会“一步一步走”的对象

在 Python 中,迭代器是一个实现了 __iter__()__next__() 方法的对象。它遵循迭代协议

  • __iter__() 返回自身(支持 for 循环)
  • __next__() 返回下一个值,若无则抛出 StopIteration
class Countdown:
    def __init__(self, start):
        self.start = start
    def __iter__(self):
        return self
    def __next__(self):
        if self.start <= 0:
            raise StopIteration
        self.start -= 1
        return self.start + 1
# 使用
for num in Countdown(3):
    print(num)  # 输出: 3, 2, 1

💡 所有可迭代对象(如 list、dict)本身不是迭代器,但可以通过 iter() 转成迭代器。

生成器(Generator):写起来像函数,用起来像迭代器

生成器是创建迭代器的“快捷方式”。你只需在函数中用 yield 替代 return,Python 自动帮你实现迭代协议!

def countdown_gen(n):
    while n > 0:
        yield n
        n -= 1
# 使用
for num in countdown_gen(3):
    print(num)  # 输出: 3, 2, 1

关键区别来了👇:

特性迭代器生成器
创建方式手写类 + __iter__/__next__函数 + yield
内存占用手动控制自动优化,极低
可读性较繁琐极简清晰 ✅
适用场景复杂状态管理流式数据、无限序列

🚀 生成器本质是语法糖,但它甜得恰到好处!

动手实践:处理大文件不崩内存

假设你有一个 10GB 的日志文件,想逐行读取并过滤错误信息:

def read_large_file(file_path):
    """生成器:按需读取,不加载全文件到内存"""
    with open(file_path, 'r') as f:
        for line in f:
            if 'ERROR' in line:
                yield line.strip()
# 使用(即使文件巨大,内存也稳如老狗)
for error_line in read_large_file('app.log'):
    print(error_line)

对比暴力做法 lines = open('app.log').readlines() —— 后者可能直接 OOM(Out of Memory)!

避坑指南 ⚠️

生成器只能遍历一次!

gen = (x for x in range(3))
list(gen)  # [0, 1, 2]
list(gen)  # [] ← 已耗尽!

解决方案:需要多次使用?转成 list,或重新调用生成器函数。

别混淆“可迭代对象”和“迭代器”

lst = [1, 2, 3]
iter(lst) is iter(lst)  # False!每次返回新迭代器
it = iter(lst)
iter(it) is it          # True!迭代器的 __iter__ 返回自己

生成器表达式 vs 列表推导式

# 列表推导式:立即计算,占内存
squares_list = [x**2 for x in range(1000000)]

# 生成器表达式:延迟计算,省内存
squares_gen = (x**2 for x in range(1000000))

延伸思考

yield from 是什么?
它用于“委托”另一个生成器,避免嵌套 for 循环。比如合并多个生成器流。

生成器能接收外部数据吗?
可以!通过 generator.send(value) 实现双向通信,常用于协程(async/await 的底层基础之一)。

为什么 range() 不是生成器?
因为它是可重复迭代的序列对象,且支持 len()、索引等操作——生成器做不到这些。

小结 & 行动号召 💡

  • 迭代器:协议驱动,手动实现,灵活但啰嗦
  • 生成器yield 一行搞定,内存友好,开发首选

下次当你需要处理“大量数据”“无限序列”或“流式输入”时,记得问自己:
“我能用生成器让它‘懒’一点吗?”

试试改写你项目中的某个循环,用生成器替代列表推导式,观察内存变化吧

到此这篇关于Python中迭代器和生成器让数据“懒”得刚刚好 的文章就介绍到这了,更多相关Python迭代器和生成器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python生成pdf文件的方法

    Python生成pdf文件的方法

    这篇文章主要介绍了Python生成pdf文件的方法,比较实用的功能,需要的朋友可以参考下
    2014-08-08
  • Python随机数用法实例详解【基于random模块】

    Python随机数用法实例详解【基于random模块】

    这篇文章主要介绍了Python随机数用法,结合实例形式分析了基于random模块的各种随机数操作常用技巧,需要的朋友可以参考下
    2017-04-04
  • 关于WARNING:Ignoring invalid distribution -pencv-python....警告信息的处理方法(已解决!)

    关于WARNING:Ignoring invalid distribution -pencv-python....

    这篇文章主要给大家介绍了关于WARNING:Ignoring invalid distribution -pencv-python....警告信息的处理方法,文中通过图文将解决的办法介绍的非常详细,对大家学习或者使用python具有一定的参考学习价值,需要的朋友可以参考下
    2023-03-03
  • Pandas技巧分享之创建测试数据

    Pandas技巧分享之创建测试数据

    学习pandas的过程中,为了尝试pandas提供的各类功能强大的函数,常常需要花费很多时间去创造测试数据,本篇介绍了一些快速创建测试数据的方法,需要的可以参考一下
    2023-07-07
  • 用python完成一个分布式事务TCC

    用python完成一个分布式事务TCC

    这篇文章主要介绍了用python完成一个分布式事务TCC,文章里我们介绍了TCC的理论知识,也通过一个例子,完整给出了编写一个TCC事务的过程,涵盖了正常成功完成,以及成功回滚的情况,需要的朋友可以参考一下文章的具体内容
    2021-10-10
  • Pytorch深度学习经典卷积神经网络resnet模块训练

    Pytorch深度学习经典卷积神经网络resnet模块训练

    这篇文章主要介绍了Pytorch深度学习经典卷积神经网络resnet模块训练,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • python集成开发环境配置(pycharm)

    python集成开发环境配置(pycharm)

    本文是python快速进阶系列文章的第一篇,给大家介绍的是python集成开发环境pycharm的配置,有需要的小伙伴可以参考下
    2020-02-02
  • Python执行Shell命令的六种方法

    Python执行Shell命令的六种方法

    在 Python 编程中,有时我们需要执行一些 shell 命令来完成特定的任务,比如文件操作、系统调用等,Python 提供了多种内建的方法来执行这些命令,每种方法都有其适用场景和特点,本文给大家介绍了Python执行Shell命令的六种方法,需要的朋友可以参考下
    2024-09-09
  • Python如何将jpg图像修改大小并转换为png

    Python如何将jpg图像修改大小并转换为png

    这篇文章主要介绍了Python如何将jpg图像修改大小并转换为png问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Python打包代码成exe可执行文件的方法总结

    Python打包代码成exe可执行文件的方法总结

    将Python代码打包成可执行文件(.exe)是一种非常有效的解决方案,能够使用户无需安装Python环境即可直接运行程序,本文整理了一些常见的方法,希望对大家有所帮助
    2024-10-10

最新评论