坚持原创输出,点击蓝字关注我吧
作者:清菡
博客:oschina、云+社区、知乎等各大平台都有。
由于微信公众号推送改为了信息流的形式,防止走丢,请给加个星标 ⭐,你就可以第一时间接收到本公众号的推送!
文章总览图 目录一、迭代器
1.迭代协议
2.什么是迭代器呢?
3.可迭代对象
4.这个是可迭代对象和迭代器的区别
二、生成器
1.什么是迭代操作?
2.生成器和迭代器有什么不同呢?
3.生成器比迭代器多了 3 种方法
4.为什么生成器有的方法,迭代器没有?
5.数据发送到生成器,在哪个地方呢?
三、系列推荐
一、迭代器 1.迭代协议一种是包含iter方法的,另一种是包含getitem方法的(比如str对象就没有iter方法,但是一样能够迭代),只要对象中包含了这两种方法的任意一种,那么这个对象就可以进行迭代操作,也就是实现了迭代协议。
2.什么是迭代器呢?生成器是迭代器的一种。迭代器的范围比生成器更广。只要可以通过next(),从里面一个一个往外面取值,都被称为迭代器。
关于要创建一个迭代器对象,那么内部要实现一个迭代器的协议。
2.1 迭代器协议实现了迭代器协议的对象(实现方式:对象内部定义了一个iter()方法)。
对象实现了__next__方法。
__next__方法返回了某个数值(当然一般情况下,我们需要的是返回这个对象的特定的数字,并且按照一定的顺序进行依次返回)。
__next__方法需要在值取完的时候,抛出stopiteration的错误信息。
3.可迭代对象有个东西需要区分,一个是迭代器,一个是可迭代对象。
只要内部实现了迭代协议的就是一个可迭代对象(可迭代对象可以进行相关的迭代操作,比如for循环,map函数等)。
可以用 for 循环进行遍历的,那么都是可迭代对象。可迭代对象不一定是迭代器,迭代器是在可迭代基础上,它内部要首先定义一个__next_方法。
迭代器内部实现了一个__next_方法,实现了这个方法之后,通过__next_这个函数才可以对这个迭代器进行一个取值。
还有个iter()方法,这个方法可将可迭代对象转换成一个迭代器。
yield和return是 2 个东西。yield只是暂停那个生成器函数。yield可以从生成器里面生成一个内容。
列表可以进行 for 循环,可以进行 for 循环遍历,它就是个可迭代对象。 列表是可以通过 for 循环遍历的,但是它不是迭代器。
迭代器是可以通过next()进行取值的。
生成器也是迭代器,生成器是可以通过next()去取值。那么,生成器它是迭代器的一种,是属于迭代器的。
你看,报错了:
# 列表 # 可迭代对象:可以for循环遍历的都是可迭代对象 li = [1,2,3,4] next(li) print(next(li))提示:列表它不是一个迭代器。
不是个迭代器,不能通过这个去取值。要把一个可迭代对象转换成一个迭代器的话,通过iter()这个函数把可迭代对象放进去,它能够返回一个迭代器。
你看,这样就能获取到了:
# 列表 # 可迭代对象:可以for循环遍历的都是可迭代对象 li = [1,2,3,4] li1 = iter(li) print(next(li1)) print(next(li1))通过iter()这个函数,来处理某个对象,它实际上相当于触发这个对象内部的一个__iter__这个方法。
咱们看看list()的源码:
通过iter()这个函数把对象li传进去的时候,它会触发li这个对象对应的__iter_这个方法。
如果通过next()去取值,把li1这个对象传进去的时候,实际上是触发这个对象的__next__方法。
它的类里面只有这个__iter__方法。
迭代器可以通过__next__取值。迭代器内部实现了__next__方法。
迭代器内部实现了 __iter__方法之外,还实现了__next__ 方法。
4.这个是可迭代对象和迭代器的区别 二、生成器生成器是迭代器的一种。
迭代器是在可迭代对象的基础上实现了__iter_方法。迭代器和生成器都可以支持迭代操作。
1.什么是迭代操作?for 循环。
2.生成器和迭代器有什么不同呢?生成器是迭代器的一种。 刚才用起来的时候好像没有什么区别,打印下这个类型看看。
可以看到,它返回的是个列表迭代器对象:
这个是生成器对象: