https://zhuanlan.zhihu.com/p/76831058
一、迭代器
1.可迭代对象:
理解1【概念】:定义了__iter__方法的对象,调用该方法会返回一个迭代器对象。字符串、list、元组、字典都是可迭代对象
理解2【意义】:实际保存的序列和在迭代工具环境中一次产生一个结果的对象【即按需求计算的虚拟序列】都是可迭代对象
2.迭代器【迭代协议】:
定义了__next__方法的对象,每次调用__next__方法的时候就返回迭代器一个值,到达末尾的时候引发一个StopIteration异常
__iter__的调用通过iter()函数实现,而__next__的调用可以通过使用内置函数next()实现:
二、生成器
1.生成器:
通过列表生成式,可以直接创建一个列表。
但是,受到内存限制,列表容量是有限的。
而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
2.生成器也是一种迭代器,但是只能对其迭代一次。
这是因为它们并没有把所有的值存在内存中,而是在运行时生成值。【迭代器是通过已有的序列生成的,而序列的值是已经存在内存中】
3.大多数时候,生成器以函数实现:
可以结合for循环使用生成器,但是生成器函数不是返回一个值,而是yield(暂且译作“生出”)一个值。
每次对生成器调用 next() 时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。
4.生成器表达式
生成器不一定要用复杂的函数表示,python提供了简洁的生成器表达式。
从形式上来看,生成器表达式和列表解析很像,仅仅是将列表解析中的[]替换为(),但是两者差别挺大,生成器表达式可以说组合了迭代功能和列表解析功能。
生成器表达式可以认为是一种特殊的生成器函数,类似于lambda表达式和普通函数。但是和生成器一样,生成器表达式也是返回生成器generator对象,一次只返回一个值。
三、迭代器和生成器的区别
生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且
生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当
发生器终结时,还会自动抛出 StopIteration 异常。