• python里的生成器


    author:headsen chen

    date:2018-03-22 10:59:46

    notice:This article created by headsen chen himself and not allowed to copy.or you will count law questions.

    1,列表生产式:
    a = [1,3,2]
    --->
    [ i*2 for i in range(10) ]
    先用i循环产生的值 *2 ,生成的值就是列表的新元素

    以前的实现方法(python软件里实现):
    a = [ ]
    for i in range(10):
         a.append(i*2)

    print(a)

    作用:简化代码

    扩展:传递变量i,也可以传递一个函数进去

    [ func(i) for i in range(10)]


    2,生成器generator:仅生成需要使用的元素,列表里用不到的元素就不生成,节省内存空间

    实例:

    ( i*2  for  i  in  range(10))

    b = ( i*2 for i in range(10))
        for i in b:
    print(i)

    0
    2
    4
    6
    8
    10
    12
    14
    16
    18


    作用:快速生成

    [ i*2 for i in range(100000000) ] ----》 1分钟的时间生成,生成式写好后立即生成。
    (补充:a = xxx len(a) 查看a生成到哪里了,取值a[10])

    b = ( i*2 for i in range(1000000)) -----》瞬间完成,压根就不生成任何元素。调用的时候再生成

    生成具体的元素:
    for i in b:
    print(i)
    ...
    ...
    ...

    取值方法:
    b._ _next_ _()

    和列表的区别:调用的时候才生成
    生成器取值的方法:

    (1),只有用这一个next方法取值,取下一个值: b._ _next_ _(),实际中用next取值应用得比较少。
    (2),只记住当前的位置,只记住当前位置的这个元素。从而达到节省内存的目的

    3,利用函数来做生成器

    3.1肺波拉起数列:除第一个第二个数外,任意一个数都可以由前两个数相加得到
    此时用列表无法实现。可以用函数定义出:
    def f(max):
         n,a,b =0,0,1
         while n<max:
         print(b) ------------》改成 yield b 就成立生成器
         a,b = b,a+b
         n =n+1
    f(10) -----》生成10个该数列:1,1,2,3,5,8,13,21,34,55


    def f(max):
      n,a,b =0,0,1
      while n<max:
      yield b
      a,b = b,a+b
      n =n+1
    print(f(100))     ------------>调用方法     <generator object fib at 0x0000000000006CJSIF5645>


    使用方法:
    def f(max):
       n,a,b =0,0,1
       while n<max:
       yield b
       a,b = b,a+b
       n =n+1
    g = f(100)
    print(g.__next__())
    print(g.__next__())
    ...

    --->
    1
    1
    ...


    作用:上面的f函数是可以在程序外来随时中断的,又可以随时的恢复启用,中间可以夹杂别的程序。
    当f程序是个很大的很慢的程序时,就可以在这中间夹杂别的程序了

    如:
    def f(max):
       n,a,b =0,0,1
       while n<max:
       yield b
       a,b = b,a+b
       n =n+1
    g = f(100)
    print(g.__next__()) ---->1
    print(g.__next__()) ---->1
    print("do some other things")

    print(g.__next__()) ----->2
    print("do some other things")
    print("do some other things")
    print(g.__next__()) ----->3
    print(g.__next__()) ----->5


    例2:

    def  f(max):
          n,a,b =0,0,1
          while n<max:
          yield b
          a,b = b,a+b
          n =n+1
          return "done"
    g = f(10)
    print("========== start loop ==========")
    for i in g:
          print(i)


    def f(max):
       n,a,b =0,0,1
       while n<max:
       yield b
       a,b = b,a+b
       n =n+1
       return "done"
    g = f(10)
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())

    运行:
    报错一个"done"的异常错误。因为取值超过了定义的10次,已经取不到值了


    改进方法:引进try:

    def f(max):
      n,a,b =0,0,1
    while n<max:
      yield b
      a,b = b,a+b
      n =n+1
      return "done" -----------就是超值范围后的报错信息,异常的时候打印的消息。
    g = f(10)

    while True: ----------> 死循环
       try: ---------------> s是一种不断的抓的方法
          x = next(g)
          print("g:",x)
       except StopIteration as e:
          print("Generator return value:",e.value)
          break

    意思是try下面的代码一旦出这个错:StopIteration (出来别的任何错都不处理)
    就执行:print("Generator return value:",e.value) 和break 跳出循环


    总结:代码带有yield的就不叫函数了。就是一个生成器了。

  • 相关阅读:
    手把手教你使用UICollectionView写公司的项目
    深入研究Block捕获外部变量和__block实现原理
    聊聊 iOS 开发中的协议
    如何快速的开发一个完整的iOS直播app(原理篇)
    萌货猫头鹰登录界面动画iOS实现分析
    浅谈 block(1) – clang 改写后的 block 结构
    iOS 开发中你是否遇到这些经验问题(二)
    iOS 开发中你是否遇到这些经验问题(一)
    iOS 本地自动打包工具
    Storyboards vs NIB vs Code 大辩论
  • 原文地址:https://www.cnblogs.com/kaishirenshi/p/8622288.html
Copyright © 2020-2023  润新知