python可迭代对象,生成器和迭代器你搞懂了么

本文主要给大家分享python中可迭代对象,生成器与迭代它们到底是什么?有什么用,彼此之间的区别与联系。

一、可迭代对象

python中提供的内建类型比如列表、元组、字典和字符串等集合类型都支持迭代操作,迭代是访问集合中元素的一种方式,迭代简单点就是遍历集合中的每个元素。对于列表,元组,字符串,set数据类型来说可以直接作用于for循环的对象统称为可迭代对象(Iterable)。

字符串迭代如下图示,通过迭代我们可以访问字符串中的每一个元素。

python可迭代对象,生成器和迭代器你搞懂了么

我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而不用太关心该对象究竟是list还是其他数据类型。

二、如何判断一个对象是不是一个可迭代对象

我们可以通过python自带的一个collections模块中的Iterable类型判断。如下例所示:

python可迭代对象,生成器和迭代器你搞懂了么

三、生成器是什么

除了序列数据类型比如列表,元组和字符串可以作用于for循环外,还有生成器也可以作用于for循环。

我们用列表生成式可以快速创建一个列表,如果列表中的元素有100万,会耗费大量的内存空间。有没有一种方法在我们需要某个元素的时候在生成,这样就比较节省空间。就像我们去餐馆吃饭一样,现吃现做,如果都提前做好了就会占用很大的空间来放置。其实生成器就是这样一种东西,在你遍历到某个元素时它才会生成某个元素,它其实保存的是一种生成元素的算法。在Python中,这种一边循环一边计算的机制我们称为生成器(generator)。

创建生成器主要有两种方式:

第一种:将一个列表生成式的[]改成()

python可迭代对象,生成器和迭代器你搞懂了么

通过上图我们发现生成器保存的是算法,如果要生成或计算下一个元素我们可以使用python中的内建函数next()获取。如下例所示:

python可迭代对象,生成器和迭代器你搞懂了么


元素多的话使用next一个一个获取显然不现实,一般会通过使用for循环来实现,因为生成器本身就是一个可迭代对象。示例如下:

python可迭代对象,生成器和迭代器你搞懂了么

第二种:创建生成器的方法在函数中使用yield关键字

当我们生成元素的算法如果比较复杂的时候,借助类似列表生成式这样的方式很难实现。这个时候我们可以借助函数来实现。

比如我们获取一个斐波那契数列的集合。

python可迭代对象,生成器和迭代器你搞懂了么

当一个函数中使用了yield关键字后,这个函数就不再是一个普通函数,而是变成一个生成器。该函数返回的是一个生成器对象。yield和return这两个关键字都是用来返回某个值,但是他们的主要区别是在函数中如果执行到return语句就会结束整个函数,而yield在返回某个值后,会在停留的位置继续向下执行,直到把整个函数体语句执行完才结束。

四.迭代器

生成器都是迭代器对象,但是列表,元组,字符串等类型虽然是可迭代对象,但它们不是迭代器,因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

把list、dict、str,tuple等可迭代对象(Iterable)变成Iterator可以使用iter()函数实现转换。

对列表直接调用next获取值就会报错,因为只有迭代器对象可以被next函数调用。

python可迭代对象,生成器和迭代器你搞懂了么

通过使用iter()函数可以将可迭代对象转为迭代器。

python可迭代对象,生成器和迭代器你搞懂了么

因此我们在执行for循环进行迭代某一个可迭代对象时,其实是等价于下图中第二个红框中的代码:

python可迭代对象,生成器和迭代器你搞懂了么

任何实现了__iter__和__next__()方法的对象都是迭代器,演示代码如下:

python可迭代对象,生成器和迭代器你搞懂了么

其中__iter__方法返回迭代器自身,而__next__方法返回迭代器中的下一个

python可迭代对象,生成器和迭代器你搞懂了么

小结:

凡是可以作用于for循环的对象都是可迭代对象。

凡是作用于next函数的对象都是迭代器。

生成器即是一个可迭代对象,又是一种特殊的迭代器,因为迭代器一般要求实现__iter__和__next__方法。

对于python中的集合类型比如列表,元组,字符串和字典它们都是可迭代对象,但是它们不是迭代器,可以通过iter函数转换为迭代器。其实可迭代对象是一个大概念;它包含生成器,序列类型(元组,字典,字符串)和迭代器。

如果你认为本文对你有价值的话,请给勇哥点个赞,你的认可是我坚持下来的最大动力。我的python专栏和爬虫专栏已经开设,有需要的话可以进行购买学习。


分享到:


相關文章: