python笔记:迭代器+生成器

迭代器:

iter1 = iter()
for x in iter1:
    print(x)

可以用于for循环的:
1.集合数据类型,如list,tuple,dict,set,str,这些都是iterable,但是不是iterator。想把这些变成迭代器对象,可以使用iter()函数。
2.generator,包括生成器和带yield的generation function,生成器都是Iterator对象,生成器不但可以使用for循环,还可以被next函数不断调用并返回下一个值。直到最后抛出stopIteration错误表示无法继续返回下一个值了。
以上可以直接作用于for循环的对象统称为可迭代对象Iterable,可以使用isinstance()判断一个对象是不是Iterable对象;
进而:
可以被next函数不断调用返回下一个值的对象成为迭代器。
凡是可以用for的,都是iterable
凡是可以用next调用的的都是iterator
list tuple dict等不是iterator,但是可以通过iter()变成iterator,然后也可以用next调用了
其实python的for循环就是不断调用next函数实现的,具体例子百度吧

类 和 迭代器的关系:定义一个迭代器类,需要实现下面两个方法:
iter__方法返回的是一个迭代器,迭代器呢又必须实现一个__next()方法,该方法实现返回下一个元素
然后实例化这个类,实例化对象就是iterator,可以使用next方法进行调用输出下一个值

探掘for循环的根本原理:
python中所有的迭代环境都会先尝试__iter__方法,
再尝试__getitem__方法,
只有在对象不支持迭代协议时,才会尝试索引
在python中实现了__iter__方法的对象是可迭代的,在这个基础上实现了next方法,此时这个对象就变成了迭代器。
实际上想让一个迭代器正常工作,至少要实现__iter__和next()这两个方法
比如 一个类想使用for循环,像list那样,那么这个类需要实现__iter__()方法,该方法返回的是一个迭代对象
然后python的for循环就会不断的调用该迭代对象的next方法去拿到循环的下一个值,指导stopiteration错误时退出循环。
根本上说,迭代器就是有next方法的对象,也就是含有__next__()函数的对象都是一个迭代器,而不是通过索引来计数
当你或者一个循环机制for循环需要下一个 项 时,调用迭代器的next方法就会获取
条目全部取出后,会报个错stopiteration,这个不是实际的错误,只是告诉调用者,迭代完成
几个特点:
1.迭代器对象从集合的第一个元素开始访问,直到所有元素都被访问完毕,只能向前,不能后退
2.可以使用isinstance方法判断一个对象是不是iterator对象
3.迭代器两个方法:iter和next
4.新增内建函数:reversed enumerate,any,all,itertools模块,range(n)返回的就是一个迭代器对象
5.还引用了三个新的内建字典方法来定义迭代:iterkeys,itervalues,iteritems
6.需要放在try。。。。except中,因为会有一个StopIteration的异常

那么灵魂拷问:那list,dict,str到底是不是iterator?
答案是否定的,因为python的iterator是一个数据流,Iterator对象可以被
next方法调用并不断返回下一个值,直到没有数据返回stopiteration错误,可以把这个数据流看作是一个有序序列,但是我们不能提前直到这个序列的下一个值和这个序列的长度,只能通过next方法实现按需计算下一个数据,所以iterator是惰性的,只有在需要返回的时候才会计算然后返回。Iterator甚至可以表示一个无限大的数据流,例如全体自然数,而使用list是永远不可能存储全体自然数的。

枚举类的应用:

for i,value in enumerate(['a','b','c']):
    print(i,value)

0  a
1   b
2   c

迭代器代码:

# 将一个类打造为一个迭代器,那就是类里需要实现__iter__  和  __next__ 这两个方法
class JclNumbers():

    def __init__(self):
        self.a = 0
        self.b = 1


    # iter方法只执行一次,只在循环开始的时候执行一次,返回的是对象本身
    def __iter__(self):
        return self

    # 需要在next方法中编写输出的逻辑,因为for循环的时候会默认调用这个方法
    def __next__(self):
        self.a,self.b = self.b,self.a+self.b
        if self.a >100:
            raise StopIteration
        return self.a

# 实例化这个类,然后将这个对象作为iter()的参数,即可将这个对象变为迭代器
jn = JclNumbers()
jn_iter = iter(jn)

# for这句做了2件事情,一是获得了一个可迭代对象,即调用了__iter__()方法;二是循环起来即调用了__next__()方法
for i in jn_iter:
    print(i)

生成器:
首先列表生成式可以生成一个列表,但是不能生成太大的,会浪费空间,如果这个列表的元素可以用某种算法推导出来,需要的时候就会生成元素,那么是不是很高效和节能呢?
在python中一边计算一边循环的机制,就是生成器generator
创建方法:
1.将列表生成式的[] 换成(),就行了
g = (x**2 for x in range(20))
print(g)
剩下的就是next(g)了,generation保存的是算法;next方法调用太麻烦,我们采用for循环更加好用;

2.生成器函数
使用生成器函数,就是函数体内有yield,每次遇到yield语句时函数会暂停执行,返回yield语句的值,并在下次执行next函数的时候,从暂停的位置继续执行,也就是说:调用一个生成器函数,返回的是一个迭代器对象;

生成器的几种方法:
Send()和throw()和close()
参考链接如下:
https://blog.csdn.net/jpch89/article/details/87036970
https://blog.csdn.net/ai2000ai/article/details/104909974

综上:
迭代器与生成器:迭代器是一个对象,生成器是一个函数

你可能感兴趣的:(python)