Python 学习之路——迭代器与生成器
一、迭代
定义:
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。
在前面的学习中,我们知道 list、tuple、str 等这些对象是可以用 for 循环进行遍历的,这种遍历的方式我们就称之为迭代。能够进行迭代行为的对象我们就称之为可迭代对象(Iterable)。 我们可以用Python的内置模块来判断一个对象是不是可迭代对象:
|
|
通过代码验证,我们之前常用的字符串、列表、元组、字典和集合都属于可迭代对象。
二、迭代器
在Python中,我们可以自定义迭代器。想要定义迭代器,那么我们就需要在我们的类中添加 __iter__() 与 __next__() 这两个魔法方法。 __iter__() 方法:返回一个特殊的迭代器对象; __next__() 方法:调用next() 函数时调用此方法。 下面我们就用迭代器来实现输出斐波那契数列:
斐波那契数列:1、1、2、3、5、8、13、21、34……
|
|
使用上面的代码我们成功实现了利用迭代器输出斐波那契数列。
迭代器的优点:
为什么在Python中我们有那么多的可迭代的容器我们却还要弄一个迭代器呢?像列表、元组等这些容器都能够实现迭代输出,为什么我们还需要自定义迭代器呢?
首先我们思考一个问题,如果我们要遍历输出 1~100000 的数字,我们用列表怎样输出呢?我们可以用列表推导式——[i for i in range(100000)]
,像这样就可以输出。但是这样有一个问题,那就是这样使用时Python解释器会将整个列表放入到内存中,这庞大的数据量必定会占用极大的内存空间。
首先就会拖累程序的运行速度,而且很有可能会产生内存溢出的风险。这就是列表的坏处。
但是如果我们使用迭代器输出,就不会有这种风险了。因为迭代器是调用的函数,输出一次调用一次函数。因此迭代器消耗的内存始终是固定的,不会有内存溢出的风险。
因此在数据较为庞大时我们应当采用迭代器输出。
三、生成器
定义:
在Python中,使用了 yield 的函数被称为生成器(generator)
生成器函数跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值(这里和return类似), 并在下一次执行 next() 方法时从当前位置继续运行。
用列表推导式创建生成器
创建列表和生成器的区别仅在于最外层的 [] 和 (),[]创建的是一个列表,而 () 创建的是一个生成器。
|
|
自定义生成器
利用生成器来实现输出斐波那契数列:
|
|
生成器和迭代器极为相似,生成器也像迭代器那样有着占据内存空间少的优点,同样适合在数据量较为庞大时使用。