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]

注意点:

  1. 因为生成器就是等到用的(比如:打印或者next函数取值等)时候才会进行计算生成,所以等到最后打印的时候才开始计算(即在本程序最后一步的时候才开始计算),而之前所做的循环都是把表达式进行了计算,并没有真的代入数值进行计算。
  2. 当开始计算数据的时候,循环已经进行了两次,两次后n的值也因此变成了10 

 

posted @   sunshine_coast  阅读(305)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示