python中的生成器其实就是一个特殊的迭代器,相比于每次迭代获取数据获得(通过next()函数)时生成元素,迭代的位置,数值返回等都需要我们设计。我们可以采用更加简洁的语法即生成器(generator)。
通过列表生成式,我们可以直接创建一个列表。但是,如果我们说我们可能会通过算法根据前面的999999个数推出100w个数,但是我们此时只需要使用到前几个数,那么通过列表保存100w个数来备用就会用到巨大的空间。而我们却不一定会用到第100w个数,白白浪费了庞大的空间。因此我们就需要用到了生成器了。
生成器并不保存所有元素,保存的是算法,每调用依次next方法就根据算法返回下一个元素的值。如果没有值就抛出StopIteration异常。这样就有一有一个好处,生成器会根据你需要的个数来返回元素的个数,不会浪费空间。因此生成器是惰性的序列。
创建生成器有俩种方法:
第一种和列表生成很相似,将[]换成了()。a此时是一个生成器对象。
第二种:
一个函数中只要有yield这个关键词,那么这个函数就变成了生成器。生成器通过next()开启,运行到yield暂停挂起。
yield有俩个作用:当运行到yield时保存当前运行状态,然后挂起。
返回yield后面表达式返回的值,相当于return。
当再次调用next()函数的时候会返回之前挂起的运行位置继续往下运行,直到运行到下一个yield为止,如果没有就会抛出StopIteration异常。
唤醒生成器除了用next()函数外也可以使用send()函数。send()方法不仅可以返回yield断点还可以传入一个值。需要注意的是生成器第一次唤醒不能使用send()方法。
在之前用迭代器实现斐波那契数列打印的时候,可以看出斐波那契数列是通过特定的算法(a,b = b, a+b)推算出下一个值的。这就跟生成器保存算法的原则就很类似了,因此用生成器实现斐波那契数列打印更加简单。