什么是生成器(generator)?
在Python中提供了一种名为generator
的对象,他是通过next
函数去中断执行并且generator
对象具有Iterable
对象,也就是说可以用于for
循环,generator
最大的作用是按需生成值,这个是什么意思呢?当我们需要一组元素很多的列表的时候会占用很大的内存,比如你需要生成一组从0-100000的列表,那么这个列表的长度将有10万,这是多么大的列表?如果比这个数值更大呢?那么很大一部分内存都将用来保存这个列表。
list(range(100000))
类似于上面这样的情况,我们可以用generator
对象来按需生成数值来供我们处理,你可以把generator
对象理解为一种状态机,里面保存着每次执行后的状态而并不是一次性的生成所有的值,我们就相当于导演,generator
对象就像一个演员,我们叫他cut的时候,他就会停止,这样的好处就是一次性只返回一个或少量的值,不会一次性大量生成所有的值而导致内存的紧缺。
生成器(generator)函数
生成器函数和普通函数很相似,为什么?因为你看见一个函数内部只要出现yield
标识符,那么这个函数肯定就是generator
对象函数,比如下面的代码:
#普通函数
def ad(a,b):
return a + b
#generator函数
def ad(a,b):
yield a + b
return None
但是他们的执行过程却不一样,普通函数调用过后就马上执行内部的代码并返回,而generator
对象函数却是保存了内部的状态,等待你需要的时候再去执行,而执行我们通过next
函数去调用并且在内部执行的时候遇见了下一个yield
标识符就会停止执行并返回yield
标识符后面的值。
#普通函数
def ad(a,b):
return a + b
#generator函数
def ad(a,b):
yield a + b
return None
#普通函数执行
ad(1,5)
#6
b = ad(1,5)
#此时保存了状态
next(b)
#6 通过next函数调用generator函数执行
生成器(generator)表达式
生成器表达式和列表表达式很像,但是有一点不同的是列表表达式由[]
组成,而生成器表达式由()
组成,就像下面的代码一样:
l = [x * x for x in range(5)]
#列表表达式
g = (x * x for x in range(5))
#生成器表达式
generator
对象是需要通过next
函数调用执行,并且返回的值是按循环生成的每个元素,我们每次用next执行我们的generator
对象后,generator
对象会保存执行后的状态,直到没有元素或者遇见return
语句后抛出一个StopIteration
错误来表示已经执行完毕,下面的代码是通过手动执行generator
对象和通过for
自动执行。
g = (x for x in range(5))
#生成器表达式
next(g)
#0
next(g)
#1
next(g)
#2
next(g)
#3
next(g)
#4
next(g)
#
Traceback (most recent call last):
File "<ipython-input-18-e734f8aca5ac>", line 1, in <module>
next(g)
StopIteration
从上面的代码看出来当我们调用内部的代码已经执行完了后,我们再次执行就会扔出StopIteration
类型的错误,当然我们也可以直接给next
设置默认返回值,当执行完内部的所有代码后就会返回这个默认值
g = (x for x in range(5))
#生成器表达式
next(g,'ok')
#0
next(g,'ok')
#1
next(g,'ok')
#2
next(g,'ok')
#3
next(g,'ok')
#4
next(g,'ok')
#返回 'ok'
《Python生成器》留言数:0