news 2026/6/2 16:27:59

Python全栈修炼之路 | 第13篇 :迭代器与生成器 —— 惰性求值的艺术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python全栈修炼之路 | 第13篇 :迭代器与生成器 —— 惰性求值的艺术

本文是《Python全栈修炼之路》系列的第13篇,属于进阶修炼篇前半部分。适合已掌握Python基础语法,希望深入理解Python核心机制的读者。


前言

在Python编程中,处理大规模数据是常见需求。当面对百万级甚至亿级数据时,一次性将所有数据加载到内存往往会导致程序崩溃。迭代器(Iterator)生成器(Generator)正是解决这一问题的利器,它们实现了"惰性求值"(Lazy Evaluation)的理念——只在需要时才计算下一个值。

本文将深入探讨Python的迭代协议、生成器机制以及itertools模块的强大功能,帮助你写出既优雅又高效的Python代码。


一、知识点讲解

1.1 可迭代协议(Iterable Protocol)

在Python中,可迭代对象(Iterable)是指实现了__iter__()方法或__getitem__()方法的对象。简单来说,任何可以用for循环遍历的对象都是可迭代的。

# 常见的可迭代对象my_list=[1,2,3]# 列表my_tuple=(1,2,3)# 元组my_string="hello"# 字符串my_dict={'a':1,'b':2}# 字典(迭代键)my_set={1,2,3}# 集合my_file=open('data.txt')# 文件对象# 检查对象是否可迭代fromcollections.abcimportIterableprint(isinstance(my_list,Iterable))# Trueprint(isinstance(my_string,Iterable))# Trueprint(isinstance(42,Iterable))# False

如何判断一个对象是否可迭代?

方法说明示例
iter(obj)尝试获取迭代器,成功则对象可迭代iter([1,2,3])
isinstance(obj, Iterable)类型检查,推荐方式isinstance([], Iterable)
hasattr(obj, '__iter__')检查是否有__iter__方法hasattr([], '__iter__')

1.2 迭代器协议(Iterator Protocol)

迭代器(Iterator)是实现了两个特殊方法的对象:

  • __iter__():返回迭代器对象自身
  • __next__():返回序列中的下一个值,没有元素时抛出StopIteration异常
classCountDown:"""自定义迭代器:倒计时"""def__init__(self,start):self.start=startdef__iter__(self):# 返回迭代器对象自身returnselfdef__next__(self):ifself.start<=0:raiseStopIteration self.start-=1returnself.start+1# 使用自定义迭代器countdown=CountDown(5)fornumincountdown:print(num,end=' ')# 输出: 5 4 3 2 1

可迭代对象 vs 迭代器的区别:

特性可迭代对象(Iterable)迭代器(Iterator)
能否重复使用可以不可以(一次性)
方法要求__iter__()__iter__()+__next__()
内存占用存储所有数据只存储当前状态
示例list, tuple, striter()返回的对象
# 关键区别演示my_list=[1,2,3]# 可迭代对象可以多次遍历foriteminmy_list:print(item,end=' ')# 1 2 3print()foriteminmy_list:print(item,end=' ')# 1 2 3(可以再次遍历)# 迭代器只能遍历一次iterator=iter(my_list)print(list(iterator))# [1, 2, 3]print(list(iterator))# [](已耗尽,为空)

1.3 生成器函数与yield

生成器(Generator)是一种特殊的迭代器,使用yield关键字定义。相比普通函数,生成器函数可以"暂停"执行并保存状态,下次从暂停处继续。

deffibonacci(n):"""生成前n个斐波那契数"""a,b=0,1count=0whilecount<n:yielda# 暂停,返回当前值a,b=b,a+b# 下次从这里继续执行count+=1# 使用生成器fornuminfibonacci(10):print(num,end=' ')# 0 1 1 2 3 5 8 13 21 34

yield的核心特性:

  1. 状态保存:每次yield后,函数的状态(局部变量、执行位置)被保存
  2. 惰性求值:只在需要时生成下一个值
  3. 自动实现迭代器协议:无需手动定义__iter____next__
defdemo_generator():print("开始执行")yield1print("继续执行,yield 1之后")yield2print("继续执行,yield 2之后")yield3print("执行结束")gen=demo_generator()print(type(gen))# <class 'generator'># 手动驱动生成器print(next(gen))# 开始执行 → 1print(next(gen))# 继续执行,yield 1之后 → 2print(next(gen))# 继续执行,yield 2之后 → 3# next(gen) # StopIteration 异常

1.4 生成器表达式

类似于列表推导式,Python支持生成器表达式,使用圆括号()代替方括号[]

# 列表推导式 - 立即计算所有值,占用内存squares_list=[x**2forxinrange(1000000)]# 占用大量内存# 生成器表达式 - 惰性求值,节省内存squares_gen=(x**2forxinrange
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 16:25:57

用Micro:bit与导电胶带复刻Stylophone:从开关电路到创客乐器

1. 项目概述&#xff1a;从经典乐器到创客实践如果你对七八十年代的电子音乐有点印象&#xff0c;或者是个复古合成器爱好者&#xff0c;那你很可能听说过Stylophone这个名字。这个由英国人布莱恩贾维斯在1967年发明的小玩意儿&#xff0c;本质上是一个用触控笔来演奏的迷你模拟…

作者头像 李华
网站建设 2026/6/2 16:24:36

未来十年热门赛道!薪资远超普通行业 3 倍,人才缺口 327 万

网络安全&#xff1a;未来十年最火的黄金赛道&#xff01;2025 年薪资将超传统行业 3 倍&#xff0c;人才缺口达 327 万&#xff01; 一、发展前景&#xff1a;政策 技术双轮驱动&#xff0c;万亿市场爆发在即 政策红利持续释放&#xff1a;《网络安全法》《数据安全法》等法…

作者头像 李华
网站建设 2026/6/2 16:22:56

抖音无水印下载终极教程:5分钟学会批量保存高清视频

抖音无水印下载终极教程&#xff1a;5分钟学会批量保存高清视频 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

作者头像 李华
网站建设 2026/6/2 16:20:34

电站智能温度巡检仪ZXJ64A测量通道

电站智能温度巡检仪ZXJ64A测量通道电站智能温度巡检仪ZXJ64A测量通道ZXJ64A型温度巡检仪表针对目前电站测温点多&#xff0c;测点分散&#xff0c;及多种热电阻而设计的。并一改以前同类仪表抗干扰能力弱的缺点&#xff0c;采用高精度恒流源对信号采集&#xff0c;采用AT90S853…

作者头像 李华
网站建设 2026/6/2 16:14:59

工业级配置文件映射方案

✅ 工业级配置文件映射方案 这是目前最推荐的生产环境方案:信号地址完全配置化,便于不同产线、不同设备复用和后期维护,无需修改代码即可调整信号地址。 1. 配置文件结构(推荐 appsettings.json 或独立 PlcSignals.json) {"PlcSettings": {"SimulateMode…

作者头像 李华