发现还有很多人对yield不理解,云里雾里,于是试着用文字表述.
只要函数含有yield语句,它就返回一个生成器.所以我们与其把其看成函数定义,不如看作是 生成器定义.函数用 return返回,而生成器用 yield返回.
接下来是yield的行为.
使用 "yield消除技术",用一个结果变量来收集yield的东西并返回.
于是转换成
而 生成器的强大魔法在于它是延迟执行的,在需要的时候它才去执行代码,它"记住"了yield的执行位置,获取下一个结果的时候从上一次yield的位置继续往下走.
所以生成器相对于list,它每个时刻只保存一个当前结果,节省了内存,缺点是无法用下标索引,遍历一次就没了.另一个好处是可以生成无穷序列,如cycle.
需要注意的是,当我们调用函数的时候,它并不开始执行函数体代码,只是返回一个生成器.
比如
只要函数含有yield语句,它就返回一个生成器.所以我们与其把其看成函数定义,不如看作是 生成器定义.函数用 return返回,而生成器用 yield返回.
接下来是yield的行为.
比如
def html():
yield 'header'
for i in range(5):
yield i
yield 'footer'
h = html()#此时h变量就是一个生成器.
for x in h:#遍历生成器
print x
怎么理解这个函数呢?
使用 "yield消除技术",用一个结果变量来收集yield的东西并返回.
于是转换成
def html():
ret = []
ret.append('header')
for i in range(5):
ret.append(i)
ret.append('footer')
return ret
可以看到,yield语句没了,所有东西都在ret这个序列.
而 生成器的强大魔法在于它是延迟执行的,在需要的时候它才去执行代码,它"记住"了yield的执行位置,获取下一个结果的时候从上一次yield的位置继续往下走.
所以生成器相对于list,它每个时刻只保存一个当前结果,节省了内存,缺点是无法用下标索引,遍历一次就没了.另一个好处是可以生成无穷序列,如cycle.
需要注意的是,当我们调用函数的时候,它并不开始执行函数体代码,只是返回一个生成器.
比如
def A():
print 'hehe'
yield 1
yield 2
当我们A()时,并不会print 'hehe',而只有当我们遍历的时候,它才开始执行,从函数体第一行代码直到第一个yield,而后继续往下执行代码到下一个yield,如此下去.