'''
生成器函数:编写为常规的def语句 ,但是使用yield语句一次返回一个结果,在每次结果之间挂起和继续他们的状态
生成器表达式:类似于列表解析,但是,他们返回按需产生结果的一个对象,而不是构建一个结果列表
生成器函数yield vs return
状态挂起
和返回一个值并退出常规函数不同,生成器函数自动在生成值的时刻挂起并继续函数的执行,挂起时保存的状态包含他们的整个本地作用域,但函数恢复时,他们的本地变量保持了信息并且使其可用
yield语句挂起该函数并向调用者发送回一个值,但是保留足够的状态以使得函数能够从他离开的地方继续,当继续时,函数从上一个yield返回后立即继续执行
'''
#for循环通过重复调用__next__方法来获取值,直到捕获一个异常
def gensquares(n):
for i in range(n):
yield i**2
for i in gensquares(5):
print(i, end=',')
x=gensquares(2)
print(next(x))
print(next(x))
#print(next(x)) #超出迭代,报错
#非生成器函数,则for循环通过索引协议进行迭代
def buildsquares(n):
res=[]
for i in range(n):
res.append(i**2)
return res
for x in buildsquares(5):
print(x, end=',')
print('************************************')
#这种情况下,send方法生成一系列结果的下一个元素,就像__next__方法一样,但是他也提供一种调用者与生成器之间的通信的方法
def gen():
for i in range(3):
yield i
g=gen()
#g.send(88) #报错:不能将非None值发送到刚启动的生成器
print(next(g)) #0 读取第一个值
print(g.send(88)) #插入88到生成器中,并返回下一个值 1
print(next(g)) #2 读取最后一个值
def gen2():
for i in range(3):
x=yield i
print(x, end='...')
g=gen2()
print(next(g)) #0 读取第一个值
print(g.send(88)) #88...1,插入88,print打印88,并返回下一个值1
print(next(g)) #2 读取最后一个值
#生成器表达式
print(list((x**2 for x in range(4))))
print(list(map(str.upper, (x for x in 'spam'))))
#生成器是单次迭代对象
g=(c*4 for c in 'spam')
i1=iter(g) #Get an iterator from an object.
i2=iter(g)
print(next(i1)) #第一个ssss
print(next(i2)) #第二个pppp
print(next(i1)) #第三个aaaa
print(next(i2)) #第四个mmmm
#print(next(i1)) #StopIteration异常
#print(next(i2)) #StopIteration异常
def timesfour(s):
for c in s:
yield c*4
g=timesfour('spam')
i1,i2=iter(g),iter(g)
print(next(i1)) #第一个ssss
print(next(i2)) #第二个pppp
print(next(i1)) #第三个aaaa
print(next(i2)) #第四个mmmm
生成器函数:编写为常规的def语句 ,但是使用yield语句一次返回一个结果,在每次结果之间挂起和继续他们的状态
生成器表达式:类似于列表解析,但是,他们返回按需产生结果的一个对象,而不是构建一个结果列表
生成器函数yield vs return
状态挂起
和返回一个值并退出常规函数不同,生成器函数自动在生成值的时刻挂起并继续函数的执行,挂起时保存的状态包含他们的整个本地作用域,但函数恢复时,他们的本地变量保持了信息并且使其可用
yield语句挂起该函数并向调用者发送回一个值,但是保留足够的状态以使得函数能够从他离开的地方继续,当继续时,函数从上一个yield返回后立即继续执行
'''
#for循环通过重复调用__next__方法来获取值,直到捕获一个异常
def gensquares(n):
for i in range(n):
yield i**2
for i in gensquares(5):
print(i, end=',')
x=gensquares(2)
print(next(x))
print(next(x))
#print(next(x)) #超出迭代,报错
#非生成器函数,则for循环通过索引协议进行迭代
def buildsquares(n):
res=[]
for i in range(n):
res.append(i**2)
return res
for x in buildsquares(5):
print(x, end=',')
print('************************************')
#这种情况下,send方法生成一系列结果的下一个元素,就像__next__方法一样,但是他也提供一种调用者与生成器之间的通信的方法
def gen():
for i in range(3):
yield i
g=gen()
#g.send(88) #报错:不能将非None值发送到刚启动的生成器
print(next(g)) #0 读取第一个值
print(g.send(88)) #插入88到生成器中,并返回下一个值 1
print(next(g)) #2 读取最后一个值
def gen2():
for i in range(3):
x=yield i
print(x, end='...')
g=gen2()
print(next(g)) #0 读取第一个值
print(g.send(88)) #88...1,插入88,print打印88,并返回下一个值1
print(next(g)) #2 读取最后一个值
#生成器表达式
print(list((x**2 for x in range(4))))
print(list(map(str.upper, (x for x in 'spam'))))
#生成器是单次迭代对象
g=(c*4 for c in 'spam')
i1=iter(g) #Get an iterator from an object.
i2=iter(g)
print(next(i1)) #第一个ssss
print(next(i2)) #第二个pppp
print(next(i1)) #第三个aaaa
print(next(i2)) #第四个mmmm
#print(next(i1)) #StopIteration异常
#print(next(i2)) #StopIteration异常
def timesfour(s):
for c in s:
yield c*4
g=timesfour('spam')
i1,i2=iter(g),iter(g)
print(next(i1)) #第一个ssss
print(next(i2)) #第二个pppp
print(next(i1)) #第三个aaaa
print(next(i2)) #第四个mmmm