美文网首页
python 中的生成器

python 中的生成器

作者: yeathMe | 来源:发表于2018-01-05 15:01 被阅读0次

1为什么要用生成器
a=[x2 for x in rang(10)] 表示使用rang(10) 中的数生成一个列表,列表中的 每一个元素都是 x2,
这样a的结果就是 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

但是如果我们 使用a=[x*2 for x in rang(110000)] 这里的range范围比较大,那么a重元素的数量就会非常多,占用很大的内存空间。

我们有这样一种需求: 每次从a中取出一个元素,但是什么时候取是不知道的,所以我们希望等到取元素的时候再计算a中的下一个元素,也就是我们保存生成a 列表的 算法范式 (x*2),这样a就会占用很小的内存空间。这就是生成器 要解决的问题。

b=(x*2 for x in range(100))
print next(b)
print next(b)
print next(b)
输出:
0
2
4

上面(x*2 for x in range(100)) 就是一个生成器,将这个生成器赋值给b引用,通过next方法可以获取生成器中的 下一个元素

2创建生成器

1,创建生成器的第一种方式,将列表的[] 改为(), a=(x2 for x in range(10)).
注意区别 a=[x
2 for x in range(10)] 这个中括号称为列表推导式, 其特点是立即生成列表中的元素。
而上面的a=(x*2 for x in range(10)). 这里返回的a是一个生成器。

  1. 带有yield的方法 被调用后会返回一个生成器对象。
def createNum():
    print "createNum start"
    i=0
    a=1
    b=1
    while i<5:
        a,b=b,a+b
        print a,b
        i=i+1
        yield b
    print "createNum stop"

generator=createNum()
print generator #<generator object createNum at 0x0000000003133900>
print next(generator)
print next(generator)


这里有一个问题, 调用含有yield方法 返回一个生成器对象,然后我们可以使用next(generator)获取下一个值,这里的这个值是哪个变量的值,是如何生成的? 这取决于yield 语句中 包含的 表达式的值。
当我们调用next(generator) 的时候,生成器会自动运行到yield语句的位置,并返回yield语句中表达式的值 。
这里包含了这两个操作。

另一个问题,上面显示 while循环将会循环5次,5次之后就退出了while,也就是说next(generator )最多调用五次,如果调用了六次,那么第六次执行next(generator)的时候将会出现错误stopIteration

3从生成器中获取元素

1,next(generator)
2,generator.next()
3 使用for循环遍历生成器对象
for x in generator

4 send 和next

def testSend():
    i=0
    while i<5:
        temp=yield  i
        print (temp)
        i=+1

generatorSend=testSend()
print next(generatorSend)
print(next(generatorSend))

输出结果:
0
None
1

当第一次运行next的时候,程序会执行到testSend方法的yield语句的地方,然后程序被挂起,此时返回i的值是0,因此next方法的返回值是0.
当第二次运行next的时候 会首先置信print(temp),然后挂起在yield语句的地方,并输出print(next(generatorSend))
但是为什么 print(temp)会输出 none?? 按照我的理解temp的值为第一次执行yield i的返回值,也就是i=temp=0。
书中给出的解释如下:


image.png

这里有一个问题, temp=yield i 和 yield i的区别,前者是yield表达式,后者是yield语句;表达式总是有值的,而语句不一定有值。
在本示例中yield是作为一个表达式使用的,这个表达式的值是yield方法返回的一个值,而这个值是通过外部send方法发送的值,所以temp的值就是send方法发送的值。

简单来说 next得到的值是yield 后面他的表达式 计算得到的值。
yield i 整体的值是send方法发送的值,temp表示将yield i整体的值赋值给temp,而不是将yield语句中内部子表达式的值赋给temp。

5 send 方法


def testSend():
    i=0
    while i<5:
        temp=yield  i
        print (temp)
        i=i+1

generatorSend=testSend()
print next(generatorSend)
print generatorSend.send("xx")
print(next(generatorSend)))
输出结果:
0
xx
None
2

从这个例子中我们可以看出send方法 有两个作用
(1)将send方法的参数作为 yield i 表达式的整体结果赋值给temp
(2)可以使得程序继续从yield挂起的地方继续往下运行,直至再次遇到yield挂起,在这一点上和next方法相同
另外补充两点
(3) send方法之前之前,程序挂起在yield语句的地方,send 方法的参数作为本次yield i整体的结果。也就说send方法只表示本次yield i整体的结果,而不影响后续 执行yield i 整体的结果。这也要求 send之前需要 先将程序挂起在yield处

(4)send(None)与next ()两个函数作用相同。

相关文章

  • python输出杨辉三角

    知识点 1. python中的生成器 generator python生成器 2. python中-1索引表示容器...

  • python生成器

    什么是python生成器? 在python中,生成器是根据某种算法边循环边计算的一种机制。 生成器有什么特点? 1...

  • python笔记

    Python format格式化输出 浅谈 Python 的 with 语句 Python中迭代原理生成器和迭代原...

  • 14-核心编程2

    生成器 概念在Python中, 一边循环一边计算的机制, 称为生成器: generator 创建生成器: G = ...

  • 理解Python中的生成器及yield关键字

    参考资料: Python生成器 python生成器到底有什么优点?

  • 生成器 迭代器 装饰器

    生成器在Python中,这种一边循环一边计算的机制,称为生成器:generator。 创建生成器要创建一个生成器,...

  • 生成器

    生成器 在python中,使用了yield的函数被称为生成器(generator)。生成器是一个返回迭代器的函数,...

  • Python 入门之 Python三大器 之 生成器

    Python 入门之 Python三大器 之 生成器 1、生成器 (1)什么是生成器? 核心:生成器的本质就是一个...

  • Python yield 的使用

    Python中,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 gene...

  • python生成器(generator)

    1.生成器(generator)概念 生成器是迭代器,生成器提供了非常方便的自定义迭代器的途径,在Python中,...

网友评论

      本文标题:python 中的生成器

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