• 生成器


    # 首先必须区分迭代器(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__()
  • 相关阅读:
    苹果 iOS 8 新固件新功能特性总结汇总 (苹果 iPhone/iPad 最新移动操作系统)
    为什么魔兽世界里男性玩家爱选女性角色?
    腾讯PK微软 王者之战一触即发
    策略模式
    代理模式
    模板模式
    适配器模式
    工厂模式
    随机森林步骤(转)
    马氏距离通俗理解(转)
  • 原文地址:https://www.cnblogs.com/tangxlblog/p/9948352.html
Copyright © 2020-2023  润新知