迭代器和生成器

https://zhuanlan.zhihu.com/p/76831058

一、迭代器

1.可迭代对象:

  理解1【概念】:定义了__iter__方法的对象,调用该方法会返回一个迭代器对象。字符串、list、元组、字典都是可迭代对象

  理解2【意义】:实际保存的序列和在迭代工具环境中一次产生一个结果的对象【即按需求计算的虚拟序列】都是可迭代对象

2.迭代器【迭代协议】:

  定义了__next__方法的对象,每次调用__next__方法的时候就返回迭代器一个值,到达末尾的时候引发一个StopIteration异常

3.迭代器和可迭代对象的关系:
  迭代器可以由可迭代对象通过内置函数iter()函数实现,该函数会接受一个可迭代对象,返回一个迭代器对象。实际上,iter()函数内部调用的是可迭代对象的__iter__方法。

 

 

4.迭代工具:
  for循环、列表解析、in成员关系、map内置函数等
5.for循环【迭代工具】的原理:
  把序列【可迭代对象】传给iter()函数,从而获得一个迭代器,返回的迭代器含有__next__方法,每次迭代中去调用__next__方法,并且捕捉StopIteration异常来确定何时离开
  

 

 


__iter__的调用通过iter()函数实现,而__next__的调用可以通过使用内置函数next()实现:

 

 

 

二、生成器

1.生成器:

通过列表生成式,可以直接创建一个列表。
但是,受到内存限制,列表容量是有限的。
而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。

 

2.生成器也是一种迭代器,但是只能对其迭代一次。

  这是因为它们并没有把所有的值存在内存中,而是在运行时生成值。【迭代器是通过已有的序列生成的,而序列的值是已经存在内存中】

3.大多数时候,生成器以函数实现:

  可以结合for循环使用生成器,但是生成器函数不是返回一个值,而是yield(暂且译作“生出”)一个值。

  每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。

 

 

4.生成器表达式

生成器不一定要用复杂的函数表示,python提供了简洁的生成器表达式。

从形式上来看,生成器表达式和列表解析很像,仅仅是将列表解析中的[]替换为(),但是两者差别挺大,生成器表达式可以说组合了迭代功能和列表解析功能。

生成器表达式可以认为是一种特殊的生成器函数,类似于lambda表达式和普通函数。但是和生成器一样,生成器表达式也是返回生成器generator对象,一次只返回一个值。

 

 三、迭代器和生成器的区别

生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且
生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当
发生器终结时,还会自动抛出 StopIteration 异常。

 

 

posted on 2020-04-18 21:34  芦荟~lh  阅读(93)  评论(0编辑  收藏  举报

导航