生成器

生成器的语法

生成器表达式: 通列表解析语法,只不过把列表解析的[]换成()

生成器表达式能做的事情列表解析基本都

能处理,只不过在需要处理的序列比较大时,列表解析比较费内存。

 1 >>> gen = (x**2 for x in range(5))
 2 >>> gen
 3 <generator object <genexpr> at 0x0000000002FB7B40>
 4 >>> for g in gen:
 5 ...   print(g, end='-')
 6 ...
 7 0-1-4-9-16-
 8 >>> for x in [0,1,2,3,4,5]:
 9 ...   print(x, end='-')
10 ...
11 0-1-2-3-4-5-

生成器函数: 在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器函数。

一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。

每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

但是生成器函数可以生产一个无线的序列,这样列表根本没有办法进行处理。

yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator。

下面为一个可以无穷生产奇数的生成器函数。

 1 def odd():
 2     n=1
 3     while True:
 4         yield n
 5         n+=2
 6 odd_num = odd()
 7 count = 0
 8 for o in odd_num:
 9     if count >=5: break
10     print(o)
11     count +=1

生成器是包含有__iter__()和__next__()方法的,所以可以直接使用for来迭代,而没有包含StopIteration的自编Iter来只能通过手动循环来迭代。

 
在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,

代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,

直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

 1 def func():
 2     a=1
 3     print('12315456')
 4     yield a
 5     print('adsfsdf')
 6     b=2
 7     yield b
 8     print('asdf')
 9     yield '123'
10 ret=func()
11 print(next(ret))
12 print(next(ret))
13 print(next(ret))
原文地址:https://www.cnblogs.com/0704L/p/7274879.html