Python之迭代器和生成器

一、迭代器

1、迭代器的概念

  迭代器即迭代的工具,那么什么是迭代呢?迭代是一个重复的过程,每一次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值。下面的代码就不是迭代.

while True:
    print('====>')

  上面代码只是单纯的重复,不是迭代。下面的代码就是迭代

1 l=[1,2,3]
2 count=0
3 while count<len(1):
4     print(l[count])
5     count+=1

二、为什么要有迭代器?什么是可迭代对象?什么是迭代器对象?

  1、为什么要有迭代器

        对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的

        迭代方式,这就是为什么要需要迭代器。

  2、什么是可迭代对象

        可迭代对象指的是内置有_iter_方法的对象,即obj._iter_.如下

1 'hello'._iter_
2 (1,2,3)._iter_
3 [1,2,3]._iter_
4 {'a':1}._iter_
5 {'a','b'}._iter_
6 open('a.txt')._iter_

  3、什么是迭代器对象

        可迭代对象执行obj._iter_()得到的结果就是迭代器对象,而迭代器对象指的是内置有_iter_又内置有_next_方法的对象,文件类型是迭代器对象

        

1 open('a.txt')._iter_
2 open('a.txt')._next_

        注意:

          迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象。

          1、迭代器协议:对象必须提供一个next()方法,执行该方法后要么返回迭代器中 的下一项,要么就引起一个StopIterator异常,以终止迭代(只能往后走不能往前退)

          2、可迭代对象:实现了迭代器协议的对象

          3、协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum(),min(),max()函数等)使用迭代器协议访问对象。

三、迭代器对象的使用

 

  

 1 dic={'a':1,'b':2,'c':3}
 2 # 得到迭代器对象,迭代器对象既有_iter_又有_next_,但是,迭代器_iter_()得到的仍然是迭代器本身
 3 iter_dic=dic.__iter__()
 4 iter_dic.__iter__() is iter_dic
 5 #True
 6 print(iter_dic.__next__())#等同于next(iter_dic)
 7 print(iter_dic.__next__())#等同于next(iter_dic)
 8 print(iter_dic.__next__())#等同于next(iter_dic)
 9 #print(iter_dic.__next__())#等同于next(iter_dic)#抛出异常StopIteration异常
10 
11 # 有了迭代器我们就可以不依赖索引取值了
12 iter_dic=dic.__iter__()
13 while 1:
14     try 
15         k=next(iter_dic)
16         print(dic(k))
17     except StopIteration
18         break
19 #这样书写太丑陋了,需要我们自己捕获异常,控制next,引出for循环

四、for循环

 

 1 #基于for循环,我们完全可以不再依赖索引去取值了
 2 dic={'a':1,'b':2,'c':3}
 3 for k in dic:
 4     print(dic[k])
 5 #for循环的工作原理
 6 """
 7     1、执行in对象的dic._iter_()方法,得到迭代器对象iter_dic
 8     2、执行next(iter_dic)将得到的值赋值给k,然后执行循环代码
 9     3、重复2过程,直到捕捉到异常StopIteration,循环结束
10 """

五、迭代器的优缺点

  优点:

    1、提供一种统一的,不依赖于索引的迭代方式

    2、惰性计算、节省内存

  缺点:

    1、无法获取长度(只有在next完毕才知道到底有几个值)

    2、一次性的不能往前走,只能往后退

六、生成器

  

 1 #只要函数内部包含有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部的代码,生成器就是迭代器
 2 def fun():
 3     print("==========>first")
 4     yield 1
 5     print("==========>second")
 6     yield 2
 7     print("==========>third")
 8     yield 3
 9     print("==========>end")
10 g=fun()
11 print(g)

posted @ 2019-05-09 10:16  王者or青铜  阅读(275)  评论(0编辑  收藏  举报