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

    # 首先必须区分迭代器(Iterator)和可迭代对象(Iterable)
    """
    1、可迭代对象(Iterable):
        一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
        一类是生成器对象,包括生成器和带 yield 的generator function。
        可迭代对象可以使用for循环遍历
    2、迭代器(Iterator):
        可以被next()函数调用并不断返回下一个值的对象称为迭代器对象。
    3、生成器对象是迭代器对象,可迭代对象不一定是迭代器对象
    4、可以使用iter()函数将可迭代对象转为迭代器对象
    """
    
    # 为什么有了列表生成式,还需要生成器呢?当我们使用列表生成式,list = [x for x in range(100000000)]时
    # 还能得到一个正确的list吗?不能!!一次性生成了100000000个数,这些数把内存空间都占满了,程序还怎么运行啊!
    # 所以生成器就是为了解决这么一个事而出现的。
    # 生成器是什么?
    # 生成器里面存放的是生成数字的一套规则(算法),返回的是一个生成器对象,假如我们同样要100000000个数
    # 生成器只存放生成这100000000个数的规则,当我们要取时,我就去拿,要拿多少由你定。
    
    
    # 创建生成器方法一
    # 第一种方法很简单,只要把一个列表生成式的 [ ] 改成 ( )
    # 返回的list并不是一个列表,更不是一个元组,而是一个生成器对象
    # 生成器保存的是算法,每次调用 next(G) ,就计算出 G 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的异常
    list = (x for x in range(10))
    print(next(list), end="	")
    # 既然生成器也是可迭代对象,那么肯定也是可以使用for循环遍历的
    for x in list:
        print(x, end="	")
    print()
    print("*" * 60)
    
    
    # 创建生成器方法二
    # 带 yield 的 generator function
    # 下面定义了斐波拉契数列的推算规则
    def fib(times):
        n = 0
        a, b = 0, 1
        print("8888")
        while n < times:
            print("-----1-----")
            t = yield b
            print("-----2-----")
            a, b = b, a + b
            n += 1
    
    
    F = fib(3)
    print(next(F))
    print(next(F))
    print(next(F))
    print("*" * 60)
    # 让我们来理解一下上面那个程序,yield 到底是什么?
    # F = fib(3)    这里是创建一个生成器对象F
    # print(next(F))    next(F)才开始正式调用生成器的function
    # 注意:遇到yield时,马上停止!!!程序不往下面走了,所以第一个next(F)只输出了888和-----1------
    # 注意:next(F)有一个返回值,返回的值时yield后面的b
    # 第二个next(F),从第一次停止的地方开始,所以不会在输出888了,输出-----2-----和-----1-----
    
    
    # __next()__
    # 使用__next()__方法也可以去除生成器中的值,和next(F)的效果是一样的
    def fib(times):
        n = 0
        a, b = 0, 1
        print("8888")
        while n < times:
            print("-----1-----")
            t = yield b
            print("-----2-----")
            a, b = b, a + b
            n += 1
    
    
    F = fib(3)
    print(F.__next__())
    print(F.__next__())
    print(F.send("haha"))
    print("*" * 60)
    
    # send()
    def fib(times):
        n = 0
        while n < times:
            temp = yield n
            print(temp)
            n += 1
    
    F = fib(3)
    print(next(F))
    print(next(F))
    print(F.send("haha"))
    # 我们可以看到yield n这个整体会返回一个数给temp,未经过处理返回的数是None
    # 我们可以F.send("haha"),这样yield n这个整理就会把发送的haha赋值给temp
    # 注意:c.__next__()等价c.send(None),所以也要小心 StopIteration 异常
    # 注意:第一次不能使用c.send("haha"),为什么呢?第一次你发送haha,但是程序第一次遇到yield的时候就停了,haha给谁呢?
    # 所以第一次不能使用c.send("haha"),解决方法:使用c.send(None)或者使用c.__next__()
  • 相关阅读:
    Java学习开篇
    《我的姐姐》
    世上本无事,庸人自扰之
    这48小时
    补觉
    淡定
    es java api 设置index mapping 报错 mapping source must be pairs of fieldnames and properties definition.
    java mongodb groupby分组查询
    linux 常用命令
    mongodb too many users are authenticated
  • 原文地址:https://www.cnblogs.com/tangxlblog/p/9948352.html
Copyright © 2011-2022 走看看