美文网首页
python生成器

python生成器

作者: 伟大的洪立 | 来源:发表于2018-03-09 22:19 被阅读0次

    什么时生成器

    通过列表生成式,我们可以直接创建一个列表。 但是, 受到内存的限制,列表的容量是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面的几个元素,那后面绝大多说元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法算出来,那么我们是否可以在循环的过程中不断推算出后续的元素呢? 这样就不必创建完整的list, 从而节省大量的空间。
    在python中,这种一边循环一边计算的机制,称为生成器:generator

    创建生成器的方法

    1. 只要把一个列表生成式的[]改成()

    生成器
    可以通过 next() 函数获得生成器的下一个返回值
    生成器
    生成器保存的是算法, 每次调用next(G),就计算出G的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIeration异常。
    当然这种不断调用next()方法太变态了, 所以,我们使用for循环,因为生成器也是可迭代对象。

    yield

    generator非常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。

    def fib(times):
        n = 0
        a, b = 0, 1
        while n<times:
            print(b)
            a, b = b, a+b
            n += 1
        return 'done'
    
    fib(5)
    

    fib函数实际上是定义了斐波那契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素, 这种逻辑其实非常类似genertor。
    只要把fib函数变成generator,只需要把print(b)改成yield b。

    def fib(times):
        n = 0
        a, b = 0, 1
        while n<times:
            yield b
            a, b = b, a+b
            n += 1
        return 'done'
    
    F = fib(5)
    next(F)
    

    在上面fib 的例子,在循环过程中不断调用 yield ,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

    简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fib(5) 不会执行 fib 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fib 函数内部的代码,执行到 yield b 时,fib 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

    send

    def gen():
        i = 0
        while i<5:
            temp = yield i
            print(temp)
            i += 1
    f = gen()
    next(f)
    

    在代码中, 执行到yield时, gen函数作用暂时保存,返回i的值;temp接收下次.send('python'), send发送的过来的值,c.next()等价c.send(None)
    send 主要是反向想函数中传递一个值
    例如:

    def demo():
      n = 10
      while n < 20:
        temp = yield n
        if temp == 1:
            print("查询了一条语句")
        elif temp == 2:
            print("更新了一条语句")
        elif temp == 3:
            print("删除了一条语句")
        n += 1
    res = demo()
    res.next()
    res.send(1)
    输出: 查询了一条语句
    

    相关文章

      网友评论

          本文标题:python生成器

          本文链接:https://www.haomeiwen.com/subject/bbmmfftx.html