• python:生成器


    生成器

    通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,会占用很大的存储空间,若仅需要访问前面一部分元素,那么绝大多数元素所占空间就白白浪费了

    所以,如果列表元素可以按照某种算法推出,那么就不必创建完整的list,从而节省大量空间。在python中,这种机制为迭代器:generator

    生成器只有在调用时才会生成相应的数据,它只记录当前位置,只有一个__next__()方法取得下一个数据(python2为next()方法)。而列表在没有调用它的情况下依然会生成数据.

    要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

    L = [x*x for x in range(10)] #列表生成式

    g = (x*x for x in range(10)) #生成器

    所以,我们创建了一个generator后,基本上不会调用__next__()方法,而是通过for 循环来迭代它

    for i in g:

      print i

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

    比如,著名的菲波那契数列(Fibonacci),出第一个和第二个数外,任意一个数都可由前两个数相加得到:

    #!usr/bin/env python
    # -*- coding:utf-8 -*-

    __author__ = "Samson"

    def fib(max):
    n,a,b = 0,0,1#注意,该句相当于t = (0,0,1),n=t[0],a=t[1],b=t[2]
    while n < max:
    print(b)
    yield b#只要有yield存在,便是一个生成器
    a,b = b,a+b
    n+=1
    return "done"
    f = fib(100)
    print(f.__next__())

    还可以通过yield实现在单线程的情况下实现并发运算的效果,如:
    #!usr/bin/env python
    # -*- coding:utf-8 -*-

    __author__ = "Samson"

    import time
    def consumer(name):
    print("%s 准备吃饺子啦!" %name)
    while True:
    jiaozi = yield#保存当前状态并返回

    print("饺子[%s]来了,被[%s]吃了!" %(jiaozi,name))


    c = consumer("lixiang")
    c.__next__()
    # b1 = "韭菜馅"
    # c.send(b1)#调用yield的同时给jiaozi传值
    # #c.__next__()
    def producer(name):
    c = consumer("A")#把函数变成生成器赋给c,里面还没执行
    c2 = consumer("B")
    c.__next__()
    c2.__next__()
    print("老子开始准备做饺子了")
    for i in range(10):
    time.sleep(1)
    print("做了1个饺子,分两半!")
    c.send(i)
    c2.send(i)
    producer("samson")
  • 相关阅读:
    git add 添加错文件 撤销
    工作流Activiti5.13学习笔记(一)
    instanceof, isinstance,isAssignableFrom的区别
    oracle表查询速度极慢的处理过程记录一下
    类里面的成员变量如果是public,为什么破坏封装
    IPv4 IPv6验证
    枚举使用
    XML之命名空间的作用(xmlns)
    XSD-JAVA
    jaxb
  • 原文地址:https://www.cnblogs.com/cansun/p/8099892.html
Copyright © 2020-2023  润新知