"yield的用法"

是对return的而一种替代,函数碰到return就直接返回了,执行到yield返回一个元素,

并使生成器(使用yield的这个函数)暂停,当再次迭代生成器时,会从yield后面继续执行,

直到遇到下一个yield或者函数结束退出。

1.当函数含有yield,这个函数就不再是普通的函数,而是会被系统默认为是一个生成器(特殊的迭代器)

2.执行到yield p, 返回p值以及整个生成器处于暂停的状态,并跳出当前函数,

执行到调用返回值p的语句

3.当再次执行到这个含有yield的生成器函数时,会自动立即执行到上次暂停的位置继续执行,

也就是从yield p这个语句继续执行

4. 因为是生成器,所以要搭配for、while等循环使用,以防止运行到生成器末尾跳出生成器函数,

就不能再yield了。

有时候,为了保证生成器函数永远也不会执行到函数末尾,会用while True: 语句,

这样就会保证只要使用next(),这个生成器就会生成一个值,是处理无穷序列的常见方法。

def fib(n):

count = 0

a,b = 1,1

while count

yield a #f(1)已经在此返回了1,但上下文信息还保存着

a,b = b,a+b #调用f(2)时才第一次执行这部分代码

count = count+1

f = fib(10) #f就是一个迭代器对象

for i in f: #配合for循环使用

print(i)

>>1,1,2,3,5,8,13,21,34,55

如果写成这样:

print(f)

会打印f在内存中的地址

"python中的迭代器和生成器"

这里主要讲语法,底层定义参考"python协程.py"文件

定义迭代器方法:

iter()可以将列表、集合转换为迭代器,迭代器与普通python对象的区别是迭代器有一个next()方法,

每次调用该方法可以返回一个值

I = iter(L)#I为L的迭代器

I.next()#返回1

I.next()#返回2

I.next()#Error:StopIteration

python中的可迭代对象:

"""

1.range迭代器(按照range不是迭代器.py的意思,这个说法不规范)

2.map,zip,filter迭代器

3.字典视图迭代器:D.keys(),D.iterms()

4.文件类型

"""

生成器是惰性迭代器:

惰性加载是说一些数据在使用时才生产出来,而不是初始化时就加载到内存里了。

'协程的定义是,一个可以随时挂起并让出CPU控制权的控制流。'惰性加载在协程中的意义在于,可以

通过将未来的控制流放在next方法中,使得程序暂时让出CPU,在需要时通过send方法转进回来。

生成器定义语法:

方法1:函数内部使用yield,函数就被解释器视为生成器

def gensquare(N):

for i in range(N):

yield i**2#状态挂起,可以恢复到此时的状态

for i in gensquare(5):#使用方法

print(i, end = '')#[0,1,4,9,16]

x = gensquare(2)#x是一个生成对象

next(x)#等同于x.__next__(),返回0

next(x)#等同于x.__next__(),返回1

next(x)#等同于x.__next__(),抛出异常StopIteration

方法2:

小括号进行列表解析

G = (x ** 2 for x in range(3))

#使用小括号可以创建所需结果的生成器generator object

next(G), next(G), next(G)

效果等同于上面例子

#(1)生成器(生成器函数/生成器表达式)是单个迭代对象

G = (x ** 2 for x in range(4))

I1 = iter(G)#这里实际上iter(G) = G

next(I1)#输出0

next(G)#输出1

next(I1)#输出4

#(2)生成器不保留迭代后的结果

gen = (i for i in range(4))

2 in gen #返回True

3 in gen #返回True

1 in gen #返回False,其实检测2时,1已经就不在生成器中