zoukankan      html  css  js  c++  java
  • 生成器

    判断是否可迭代和是否迭代器
    from collections import Iterable,Iterator
    print(range(10000))
    print(isinstance(range(10000),Iterable)) #是否可迭代
    print(isinstance(range(10000),Iterator)) #是否可以变成迭代器
    输出结果
    range(0, 10000)
    True
    False

    #python2 range 不管range多少 会生成一个列表,这个列表将用来存储所有的值
    #python3 range 不管range多少 都不会实际的生成任何一个值

     
    生成器 -- Generator
    自己写的迭代器,就是生成器
    两种自己写生成器(迭代器)的机制,生成器函数,生成器表达式

    (1)生成器函数
     def func():
      print('****')
      yield 1   #凡是带有yield的函数就是一个生成器函数
      print('#####')
      yield 2   #记录当前所在的位置,等待下一次next来触发函数的状态
     g = func()
     print('1111',next(g))
     print('2222',next(g))
     #生成器函数的调用不会触发代码的执行,而是会返回一个生成器(迭代器)
     #想要生成器函数执行,需要用next

    生成器函数的案例
     def cloth_g(sum): #g表示生成器
      for i in range(sum):
       yield 'cloth %s'%i  #凡是带有yield的函数就是一个生成器函数

     g = cloth_g(100)
     print(next(g))
     print(next(g))
     print(next(g))
     结果
     cloth 0
     cloth 1
     cloth 2
     
    #使用生成器监听文件输入的例子
     import time
     def listen_file(): #生成器
      with open('userinfo') as f: #1
       while True:          #2
        line = f.readline() #3
        if line.strip():
         yield line.strip()
        time.sleep(0.1)

     g = listen_file()
     for line in g:
      print(line)
      
    #send关键字
     def func():
      print(11111)
      ret1 = yield 1
      print(22222,'ret1 :' ,ret1)
      ret2 = yield 2
      print(33333,'ret2 :' ,ret2)
      yield 3
     g = func()
     print(next(g))
     print(g.send('alex')) #在执行next的过程中,传递一个参数,给生成器函数的内部
     print(g.send('金老板'))

     11111
     1
     22222 ret1 : alex
     2
     33333 ret2 : 金老板
     3

     
    #预激生成器
     def init(func):
      def inner(*args,**kwargs):
       ret = func(*args,**kwargs)
       next(ret)  # 预激活
       return ret
      return inner

     @init
     def average():
      sum_money = 0
      day = 0
      avg = 0
      while True:
       money = yield avg
       sum_money += money
       day += 1
       avg = sum_money/day

     g = average()
     print(g.send(200))
     print(g.send(300))
     print(g.send(400)) 
     
    #yield from
     def gen_func():
      # for i in range(5):
      #  yield i
      # for j in 'hello':
      #  yield j
      #或
      yield from range(5)
      yield from 'helle'
     g = gen_func()
     #第一种取值 #随时都可以停止,最后一次会报错
     print(next(g))

     #第二种取值 for 从头到尾不遇到break return不会停止
     for i in g:
      print(i)

     #第三种取值 list或tuple  数据类型的强转,会把所有的数据都加载到内存里,非常的浪费内存
     print(g)
     print(list(g))

     <generator object gen_func at 0x0000023F3F68EF68>
     [0, 1, 2, 3, 4, 'h', 'e', 'l', 'l', 'o'] 
     
    生成器总结函数:
    # 生成器函数,是我们python程序员实现迭代器的一种手段
    # 主要特征是载函数中,含有yield
    # 调用一个生成器函数,不会调用这个函数中的代码,只是会获得一个生成器(迭代器)
    # 只有从生成器中取值的时候,才会执行函数内部的代码,且每获取一个数据才执行得到这个数据的代码
    # 获取数据的方式包括 next send 循环,数据类型的强制转化
    # yield 返回值的简便方法,如果本身就是循环一个可迭代的,且要把可迭代数据中的每一个元素都返回,可以用yield from
    # 使用send的时候,在生成器创造出来之后需要进行预激,这一步可以使用装饰器完成

  • 相关阅读:
    学长帮帮忙—Beta冲刺(4/7)
    学长帮帮忙—Beta冲刺(3/7)
    【二食堂】二食堂很难排队 博客目录
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
  • 原文地址:https://www.cnblogs.com/liwei-python-21/p/8976743.html
Copyright © 2011-2022 走看看