生成器
Posted pythonerLau
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生成器相关的知识,希望对你有一定的参考价值。
生成器:
生成器值得时生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器
生成器函数
函数体中包含yield语句的函数,返回生成器对象
生成器对象,是一个可迭代对象,是一个迭代器
生成器对象,是延迟计算,惰性求值
生成器示例(1,1):
def inc(c): y=(i for i in range(5))
for i in range(5): print(type(y))
yield i print(next(y))
print(type(inc)) print(next(y))
print(type(inc())
for m in x:
print(m.‘*‘)
for m in x:
print(m,‘**‘)
代码(1,1)分析:
普通的函数调用fn,函数会立即执行完毕,但是生成器函数可以使用next函数进行惰性求值
生成器数等价于生成器表达式,只不过生成器函数可以更加的复杂
代码(1,2):
def foo():
print(‘hello‘)
yield ‘world‘
print("we‘a")
yield ‘chinese‘
print(‘love‘)
yield ‘china‘
print(‘emm‘)
return ‘bye
代码(1,2)分析:
在生成器函数中使用多个yield语句,执行一次后会暂停,并返回yield表达式的返回值
再次执行该生成器函数时,会向下执行到下一个yield语句
return语句依然可以终止函数运行,但是return语句的返回值不会获取到
return会导致无法继续获取下一个值,抛出StopIteration
如果函数没有显示的return语句,如果生成器函数执行到结尾,一样会抛出StopIteration异常
生成器函数总结:
包含yield语句的生成器函数生成 生成器对象的时候,生成器函数的函数体不会立即执行
next(迭代器or生成器) 会从函数的当前位置向后执行到之后碰到的第一个yield语句,会弹出值,并暂停函数的运行
再次调用函数,会重复上述的步骤
当没有多余的yield语句被执行时,继续调用next()函数,会抛出StopIteration异常
生成器应用:
无限循环
def counter(): def counter():
i = 0 i=0
while True: while True:
i+=1 i+=1
yield i yeild i
def inc(c): def inc():
return next(c) c = counter()
return next(c)
c=counter() print(inc(c))
print(inc(c)) print(inc(c))
print(inc(c)) print(inc(c))
左侧显示为1,2.右侧显示为1,1,1
def inc():
def counter():
i=0
while True:
i+=1
yield i
c= counter()
return lamdba : next(c)
foo=inc(c)
print(foo())
print(foo())
lambda 表达式是匿名函数
return 返回的是一个匿名函数
等价于:
def inc():
def counter():
i=0
while True:
i+=1
yield i
c = counter()
return lambda : next(c)
foo= inc()
print(foo())
print(foo())
返回结果为 1,2
协程
生成器的高级用法
比线程,进程轻量级
实在用户空间调度函数的一种实现
协程调度器实现思路:
有2个生成器
next(A)后,A,B
next(A),A 执行到了yield 语句暂停,在执行next(B),B执行到yield语句也暂停,然后再次调用next(A),再调用next(B),周而复始,实现了调度的效果
可以引入调度的策略来实现切换的方式
协程是一种非抢占式调度
def ince(): def inc():
for x in range(1000): yield from range(1000):
yield x foo = inc()
print(next(foo))
foo=inc() print(next(foo))
print(next(foo)) print(next(foo))
print(next(foo))
print(next(foo))
以上是关于生成器的主要内容,如果未能解决你的问题,请参考以下文章