加了yeild的函数就是生成器,该函数的对象就是返回的迭代器
迭代器不能回退,只能往前进行迭代;
tips(协程使用了python关键字yield将调用者挂起和恢复执行)
def demoIterator(): #定义一个迭代器函数
print("I'm in the first call of next()")
yield 1
print("I'm in the second call of next()")
yield 2
print("I'm in the third call of next()")
yield 9
函数不赋值对象调用
记住上方所说的函数的对象返回的是迭代器,这里先不进行赋值给对象,会出现,永远只调用第一次;
原因也许是每次next()访问的函数又重新加载了一遍
print(next(demoIterator())) # I'm in the first call of next() 1
print(next(demoIterator())) # # I'm in the first call of next() 1
给函数赋值给对象,
a = demoIterator()
print(next(a)) # I'm in the first call of next() 1
print('---'*20)
print(next(a)) # I'm in the second call of next() 2
用for语句来循环迭代器
for i in demoIterator():
print(i)
range()函数生成一个列表,常被for用来做循环,for语句将列表封装成迭代器后访问。
for i in range(4):
print(i,end='\t') # 0 1 2 3
使用iter()函数可以使集合列表转化为迭代器
n = [1,2,3,4,5,6]
a = iter(n)
print(a) # <list_iterator object at 0x00000186A6360710>
for i in a:
print(i,end='\t') # 1 2 3 4 5 6
字典列表元组生成器语法
也称为字典列表元组的推导式https://www.cnblogs.com/wkhzwmr/p/15086014.html
迭代器可以使用next(),send(),throw(),close()
next()
开始一个生成器函数的执行或者从上次执行的 yield 表达式位置恢复执行。
具体是通过调用 iterator 的 next() 方法获取下一个元素。所以也可以使用__next__()来对迭代器遍历。
如果迭代器耗尽,则返回给定的 default,如果没有默认值则触发 StopIteration。
tips:只有元组生成器生成迭代器对象
tuple1=(233,32,57,44,83,590,651)
tuple2=(x for x in tuple1 if x<100)
print(tuple2.__next__()) # 32
print(tuple2.__next__()) # 57
print(tuple2.__next__()) # 44 #到此为止,生成器中的元素还未打印完
print(tuple(tuple2)) # (83,);最后一个83
send()
恢复执行并向生成器函数“发送”一个值。 value 参数将成为当前 yield 表达式的结果。
send() 方法会返回生成器所产生的下一个值,或者如果生成器没有产生下一个值就退出则会引发 StopIteration
send() 方法必须是value=None时候才能传递
throw()
在生成器暂停的位置引发 type 类型的异常,并返回该生成器函数所产生的下一个值。
如果生成器没有产生下一个值就退出,则将引发 StopIteration 异常。
close()
在生成器函数暂停的位置引发 GeneratorExit。 如果之后生成器函数正常退出、
关闭或引发 GeneratorExit (由于未捕获该异常) 则关闭并返回其调用者。
如果生成器产生了一个值,关闭会引发 RuntimeError。
如果生成器引发任何其他异常,它会被传播给调用者。 如果生成器已经由于异常或正常退出则 close() 不会做任何事。
python官方的例子
def echo(value=None):
print("Execution starts when 'next()' is called for the first time.")
try:
while True:
try:
value = (yield value)
except Exception as e:
value = e
finally:
print("Don't forget to clean up when 'close()' is called.")
generator = echo(1)
print(next(generator)) # Execution starts when 'next()' is called for the first time.
print(next(generator)) # 1
print(generator.send(2)) # None
generator.throw(TypeError, "spam") # 2
generator.close() # Don't forget to clean up when 'close()' is called.