1、迭代器
迭代是Python中访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter()和next()。
示例如下:
2、生成器
在Python中,使用yield的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到yield的函数会暂停并保存当前所有的运行信息,返回yield的值,并在下一次执行next()方法时从当前位置继续运行。
通过列表生成式,我们可以直接创建一个列表,但是受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白年后了,所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这种就不必创建完整的list,从而节省大量的空间。Python中,这种一边循环一边计算的机制,称为生成器(generator)。
生成器是这样一个函数,它记住上一次返回时在函数体中的位置,对生成器函数的第二次(或更多次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅记住了它的数据状态,还记住了它在流控制构造中的位置。
生成器的特点:
l节约内存
l迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的。
以上关于生成器的说明,大家是不是看完后一脸懵逼呢?笔者以斐波拉契数列为例,展开生成器的解析,期望大家能了解生成器。
斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1,1,2,3,5,8,13,21,34,...
while函数示例:
生成器示例:
有yield的程序流程示例:
没有yield的程序流程示例:
没访问过迭代器里面的值示例:
访问过迭代器里面的值两次示例:
为了读者更加详细的了解生成器,笔者在几个关键点添加了print命令,读者可以更好的理解生成器的运行顺序。
没有yield的时候,程序是按照顺序执行的,有了yield后,该循环只有取值的时候才会调用一次循环体,一个循环体执行完yield后暂停,回到原取值位置,如果不取值,甚至不会调用。
笔者用一图来说明Python生成器,第一次循环和第二次循环用不同的虚线标注,读者可以很清晰的了解yield的运行流程。