python3系列五可迭代对象、迭代器和生成器
1.可迭代对象
字符串、集合、列表、字典、元组都是可迭代的对象,数字不是可迭代的,就是可以通过for循环取出元素的对象,都是可迭代对象
如果查看一个变量是否为可迭代:
s = {1, 2, 3, 4} print(type(s)) #<class 'set'> print(isinstance(s,Iterable))
可以被迭代要满足的要求就是可迭代协议,可迭代协议就是内部实现了__iter__方法,即可迭代对象封装中有__iter__方法。
2.迭代器
用变量调用__iter__后就生成一个迭代器,迭代器遵循迭代器协议,必须拥有__iter__方法和__next__方法。
s_iter = s.__iter__() #s_iter是一个迭代器变量 print(s_iter) print(s_iter.__next__())
3.生成器
本质是一个迭代器,不过是由程序员写出来的就叫生成器,系统内置的就叫迭代器;
- 生成器的两种实现方式:
1)生成器函数
常规函数定义,但是,使用yield语句而不是return语句返回结果;yield语句执行一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从其离开的地方继续执行。例如:
def func(): yield from range(4)
2)生成器表达式
类似于列表推导,把列表解析的[]换成()得到的就是生成器表达式,但是生成器返回按需产生的结果的一个对象,而不是一次构建一个结果列表;
列表推导方式和生成器都是一种边里的编程方式,只不过生成器更节省内存。
g=(i for i in range(4)) #g是一个生成器
- 生成器的好处
其不会一下子在内存中生成太多数据,只是在你要的时候才会返回你要的数据。
- 生成器的例题:
def add(n,i):
return n+i def test(): for i in range(4): yield i g = test() # for n in [1,10]: # g =(add(n,i) for i in g)
# 上面的for循环套用迭代器,等价如下,遇到for循环套生成器,就拆开来做
n = 1 g = (add(n, i) for i in g) n = 10 # 覆盖前面n的值 g = (add(n, i) for i in g)
分析:
g只是代表一个生成器对象,没有for,next,list,tuple调用它的时候它是不会执行的,真实的代码执行逻辑如下:
第1次:n = 1, 执行g=(add(n,i) for i in test())
第2次:n = 10,执行g=(add(n,i) for i in (add(n,i) for i in test())) )
g因为前面做过定义,每次需要把之前定义的带入,所以当n=10 的时候,g=(add(10,i) for i in (add(n,i) for i in test())) )),最终的执行结果是[20, 21, 22, 23]
注意点:
- 因为生成器就是等到用的(比如:打印或者next函数取值等)时候才会进行计算生成,所以等到最后打印的时候才开始计算(即在本程序最后一步的时候才开始计算),而之前所做的循环都是把表达式进行了计算,并没有真的代入数值进行计算。
- 当开始计算数据的时候,循环已经进行了两次,两次后n的值也因此变成了10
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现