zoukankan      html  css  js  c++  java
  • day04.3-生成器

    1. 生成器

         生成器可以理想为一种数据类型,这种数据类型自动实现了迭代器协议(其他数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象。

    2. 生成器分类及在python中的表现形式

    • 生成器函数:利用常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的运行状态,以便下次从离开的地方继续执行。
     1 def test():
     2     yield 1
     3     yield 2
     4     yield 3
     5 res = test()
     6 print(next(res))
     7 print(next(res))
     8 print(next(res))
     9 
    10 """
    11 运行结果:
    12     1
    13     2
    14     3
    15 结果分析:下一次next从上一次next返回退出的地方进入
    16 """
    • 生成器表达式:类似于列表解析,但是,生成器返回按需产生结果的一个对象,而不是一次性构建一个结果列表。
     1 test = (item for item in range(4))
     2 print(next(test))
     3 print(next(test))
     4 print(next(test))
     5 
     6 """
     7 运行结果:
     8     0
     9     1
    10     2
    11 结果分析:下一次next从上一次next返回退出的地方进入
    12 """

    3. 生成器的优点

    • 延迟计算。即一次只返回一个结果,也就是说,生成器不会一次性生成所有的结果,这对于大数据量的处理将会非常有用。
    • 生成器还能有效地提高代码的可读性。

       注意:生成器只能从头到尾遍历一次。

    4. 生成器实例1

       "人口信息.txt"文件内容:

    1 {"name":"北京","population":1600000}
    2 {"name":"南京","population":2100000}
    3 {"name":"山东","population":2800000}
    4 {"name":"山西","population":1800000}

          "bin.py"文件内容:

     1 def get_information_population(filename):
     2     with open(filename) as p:
     3         for line in p:
     4             res = eval(line)
     5             yield res["population"]
     6 
     7 res = get_information_population("人口信息.txt")
     8 sum_people = sum(res)
     9 for item in res:
    10     print(item)
    11 
    12 """
    13 结果分析:执行上面这段代码,将不会有任何输出,这是因为,生成器只能遍历一次。在我们执行sum语句的时候,就已经遍历了一次生成器,从而,在之后当我们再次遍历生成器的时候,将不会有任何记录。所以,上面的代码不会有任何的输出
    14 因此,生成器的使用过程中,需要特别注意的就是:生成器只能遍历一次
    15 """

     5. 生成器实例2

     1 def test():
     2     x = ""
     3     print("第一次")
     4     print(x)
     5     x = yield 1
     6     print("第二次")
     7     print(x)
     8     yield 2
     9 
    10 res = test()
    11 print(next(res))
    12 print(res.send(""))
    13 
    14 """
    15 运行结果:
    16     第一次
    17 18     1
    19     第二次
    20 21     2
    22 结果分析:yield 3相当于return控制的是函数的返回值。x = yield的另外一个特征,接受send传过来的值,赋值给x
    23 """

    6. 生产者——消费者模型

     1 import time
     2 def consumer(name):
     3     print("I am %s, I start to count" %name)
     4     while True:
     5         num = yield
     6         time.sleep(1)
     7         print("I am %s, I have counted %s" %(name,num))
     8 def producer():
     9     c1 = consumer("Alix")
    10     c2 = consumer("Bob")
    11     next(c1)
    12     next(c2)
    13     for item in range(1,3,1):
    14         time.sleep(1)
    15         c1.send(item)
    16         c2.send(item)
    17 producer()
    18 
    19 """
    20 运行结果:
    21     I am Alix, I start to count
    22     I am Bob, I start to count
    23     I am Alix, I have counted 1
    24     I am Bob, I have counted 1
    25     I am Alix, I have counted 2
    26     I am Bob, I have counted 2
    27 """
  • 相关阅读:
    c++ 从vector扩容看noexcept应用场景
    c++11-17 模板核心知识(十一)—— 编写泛型库需要的基本技术
    动态链接的PLT与GOT
    c++11-17 模板核心知识(十)—— 区分万能引用(universal references)和右值引用
    Golang性能分析与优化
    c++11-17 模板核心知识(九)—— 理解decltype与decltype(auto)
    [LuoguP4808][CCC 2018]平衡树(数论分块+记忆化搜索)(有复杂度证明)
    [NOI2016]区间(线段树+尺取法)
    [BZOJ4316]小C的独立集(仙人掌+树形DP)
    [CTSC2002]灭鼠行动(模拟)
  • 原文地址:https://www.cnblogs.com/zizaijiapu/p/10590701.html
Copyright © 2011-2022 走看看