• Python 基础之生成器


    一.生成器表达式

    生成器本质是迭代器,允许自定义逻辑的迭代器
    迭代器和生成器区别:
    迭代器本身是系统内置的,重写不了.而生成器是用户自定义的,可以重写迭代逻辑
    生成器可以用来钟方式创建:
        (1)生成器表达式(里面是推导式 外面是圆括号)
        (2)生成器函数 (def定义,里面含有yield)

    #(1) 生成器表达式 generator
    #[1,2,3,4] => [4,8,12,16]
    #i<< 2 i乘以2的2次幂
    gen = (i<<2 for i in range(1,5))
    print(gen)
    from collections import Iterable,Iterator
    print(isinstance(gen,Iterator))

    ##(1)使用next进行调用生成器
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen )
    print(res)
    res = next(gen)
    print(res)
    #res = next(gen )  #StopIteration
    #print(res)        #越界
    ##(2)使用for循环调用生成器
    gen  = (i<<2 for i in range(1,5))
    for i in gen:
        print(i)
    ##(3)for next 搭配调用生成器
    gen = (i<<2 for i in range(1,5))
    for i in range(2):
        res = next(gen)
        print(res)

    二.生成器函数

    (def定义,里面含有yield)
    #yield类似于return
    共同点在于: 执行到这句话都会把值返回出去
    不同点在于: yield每次返回时,会记住上次离开时执行的位置,下次在调用生成器,会从上次执行的位置往下走
        return 直接终止函数,每次重头调用
    yield 6  yield(6)  2中写法都可以  yield 6 更像 return 6  的写法 推荐使用

    from collections import Iterator,Iterable
    #(1)基本使用
    '''如果函数当中包含了yield,那么这个函数是生成器函数'''
    def mygen():
        print("one")
        yield 1
        print("two")
        yield 2
        print("three")
        yield 3

    #初始化生成器函数 => 返回一个生成器对象,简称生成器
    gen = mygen()
    print(isinstance(gen,Iterator))
    #调用生成器
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    #res = next(gen)
    #print(res)

    #代码解析:
    首先初始化生成器函数 返回生成器对象 简称生成器
    通过next进行调用
    第一次调用时候
    print(one)
    yield 1 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回1,等待下一次调用
    第二次调用时候
    print(two)
    yield 2 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回2,等待下一次调用
    第三次调用时候
    print(three)
    yield 3 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回3,等待下一次调用
    第四次调用时候
    因为没有yield返回值了 ,所以直接报错..
    #(2)优化代码
    def mygen2():
        for i in range(1,101):
            yield "我的球衣号%d" %(i)

    #初始化生成器 返回生成器对象  简称生成器
    gen2 = mygen2()

    for i in range(50):
        res = next(gen2)
        print(res)


    #(3) send 把值发送给一个yield
    ### send
    #next  send 区别:
        next只能取值
        send不但能取值,还能发送值
    #send注意点
        第一个 send 不能给 yield 传值 默认只写None
        最后一个yield 接受不到send 的发送值
    #:
    def mygen():
        print("start")
        res = yield 1
        print(res)

        res = yield 2
        print(res)

        res = yield 3
        print(res)

        print("end")

    #初始化生成器函数 返回生成器
    send 在一次调用的时候,必须给参数None  gen send(None)
    是一个硬性要求的语法(因为第一次调用的时候,没有遇到一个yield)

    gen = mygen()
    res = gen.send(None)
    print(res)
    res = gen.send(111)
    print(res)
    res = gen.send(222)
    print(res)
    # res = gen.send(333)
    # # print(res)

    #代码解析:
    第一个调用时,必须使用gen.send(None)
    print(start)
    res = yield 1记录当前代码执行的位置状态,添加阻塞并返回1,等待下一次调用
    第二次调用时,
    send先发送,再返回,发送yield 1 res 接收到了111这个值
    print(111)
    res = yield 2 记录当前代码执行的位置状态,添加阻塞并返回2 ,等待下一次调用
    第三次调用时,
    send先发送,再返回,发送yield  2 res接收到222这个值
    print(222)
    res = yield 3 记录当前代码执行的位置状态 添加阻塞并返回3 ,等待下一次调用
    第四次调用时,
    因为没有yield继续返回了,直接报错,越界错误
    如果仍然想要执行后面没有走完的代码,比如95 96 ,那么要通过try ...except 异常处理来解决

    #异常处理格式:
    try :
        lst = [1,2]
        print(lst[99])
    execpt:
        pass

    ### yield from :将一个可迭代对象变成一个迭代器返回

    #:
    def mygen():

        #yield ["陈桂涛","五金玲","张俊林"]
        yield from ["陈桂涛","五金玲","张俊林"]

    #初始化 一个生成器mygen 返回生成器
    gen = mygen()
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)

    #用生成器写斐波那契数列

    #:
    # 1 1 2 3 5 8 13 21 ...
    def mygen(n):
        a = 0
        b = 1
        i = 0
        while i< n:
            #print(b)
            yield b
            a,b = b,a+b
            i+=1
    gen = mygen(10000)
    for i in range(20):
        res = next(gen)
        print(res)

  • 相关阅读:
    单词篇:(单词应用10~11)
    单词篇:(单词识记11)
    单词篇:(单词识记10)
    单词篇:(单词识记8~9)
    单词篇:(单词应用9)
    单词篇:(单词识记8)
    单词篇:(单词应用6~7)
    单词篇:(单词识记7)
    单词篇:(单词识记6)
    单词篇:(单词应用4~5)
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/10887185.html
Copyright © 2020-2023  润新知