迭代器、生成器

迭代器、生成器

迭代器

  • 可迭代对象

 

 

    • 可迭代对象定义: 像字符串、字典、列表以及集合这种可以使用for循环的成为可迭代对象。
    • 可迭代对象的判断:内部必须有一个__iter__的方法,遵循可迭代协议。 
        • 判断方法
          1. 判断:__iter__  in dir(对象)波尔值。
          2. 利用isinstance来判读数据类型。         
1 from collection import iterable
2 li = [1,2,3,55,1]
3 print(isinstance(li,Iterable))
    • 将可迭代对象转化为迭代器。
        • li.__iter__()→迭代器
    • 迭代器不只有__iter__(),还有__next__(),遵循迭代协议。__next__()只在迭代器里有,可迭代对象里面没有。
    • l = [1,2,3,4]
      l_iter = l.__iter__()  # 将可迭代的转化成迭代器
      item = l_iter.__next__()
      print(item)
      item = l_iter.__next__()
      print(item)
      item = l_iter.__next__()
      print(item)
      item = l_iter.__next__()
      print(item)
      item = l_iter.__next__()
      print(item)
      View Code

       

  • 迭代器  

    • 判断迭代器

          1. 用“__iter__()”或者“__next__()”in dir(迭代器名称)来判断

          2. 用isinstance()来判断。 迭代器类型为Iterator。        

    • 迭代器的用处以及意义

        1. 可以节省大量的内存空间
        2. 满足惰性机制;
        3. 不能反复取值,不可逆。
    • for循环机制
          1. 将可迭代对象转化为迭代器;
          2. 内部使用了__next__()取值。
          3. 使用了异常处理模块来处理异常情况。 

      用while 循环模拟for循环机制。 

 

1 l2 = [1, 2, 3, 4, 5, 6, 7, 8]
2 l2_obj = l2.__iter__()
3 while True:
4     try:
5         i = l2_obj.__next__()
6         print(i)
7     except Exception:
8         break

 

 

  生成器

    • 定义:本质上也是一个迭代器。一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。    

    • 生成器的产生方式:

        1. 生成器函数构造:常规函数定义。但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次在它离开的地方继续执行。

        2. 生成器推导式构造

        3. 数据类型的转化

 

 1 def fun2():
 2     print("哈罗")
 3     print("日了狗")
 4     yield "吃了吗你"
 5     yield "打死你"           ###函数中只要有yield,该函数就不是一个函数,而是一个生成器。
 6     yield "亚索"
 7 g = fun2()                  ###g称作函数生成器
 8 print(g.__next__())
 9 print(g.__next__())
10 print(g.__next__())

 

1 哈罗
2 日了狗
3 吃了吗你
4 打死你
5 亚索

 

1 def func1():
2     for i in range(10000):
3         yield ("阿里工号%s"%(i))
4 g = func1()
5 
6 for i in range(1,51):
7     print(g.__next__())
8 for j in range(151):    ###接着上面的数字打,所以从51开始往后输出150个数字、不可逆。
9     print(g.__next__())
    • send()函数

      • send跟__next__()功能一样,都是只运行一次。

      • send可以给上一个yield赋值。
1 def generator():
2     print(123)
3     content = yield 1
4     print(content)
5     print(456)
6     yield 2
7 g = generator()
8 print(g.__next__())
9 print(g.send('hello'))    ###给 yield1 赋值、

输出结果:

1 123
2 1
3 hello
4 456
5 2
  • 备注:
    • 第一次使用生成器的时候,必须要用要用next来获取下一个值。
    • 最后一个yield不能接受外部的值。  

 

1 l = [i for i in range(10)]
2 print(l)
3 l1 = ['选项%s'%i for i in range(10)]
4 print(l1)

备注:

  1. 把列表解析的[]换成()得到的就是生成器表达式
  2. 列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

                       

posted on 2018-04-03 15:31  弃疾  阅读(104)  评论(0)    收藏  举报

导航