1、迭代器(iterator)
迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。 迭代器有两个基本的方法:iter() 和 next()。
iter()创建迭代器对象
字符串,列表或元组,集合对象都可用于创建迭代器。
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素 1
>>> print (next(it)) 2
2、生成器(generator)
什么是yield呢
yield 的作用就是把一个函数变成一个generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个生成器,如调用Xun函数,不会执行该函数,而是返回一个iterable迭代对象! 区别:与return类似,都可以返回值,但不一样的地方,yield可以返回多次值,而return只能返回一次。
def Xun(max):
n=0
b=1
while n < max:
yield b
print(b)
b+=1
n = n + 1
什么是生成器
使用了 yield 的函数被称为生成器。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次从当前位置继续运行。
def f():
print('start')
a = yield 1
print(a)
print('middle....')
b = yield 2 # 2这个值只是迭代值,调用next时候返回的值
print(b)
print('next')
c = yield 3
print(c)
a = f()
print(next(a)) #1
print(next(a)) #2
print(next(a)) #3
代码执行说明:
1、执行第一个next的时候,函数f()执行print('start'),然后执行yield 1,返回给调用者,结果是1,被打印出来。程序停留在yield 1,迭代器记住此时的执行的位置。
2、执行第二个next的时候,函数f() 执行 a = yield 1的赋值操作,此时a是None,赋值没有内容;执行print(a)打印结果为None;执行print('middle....');然后执行yield 2,返回给调用者,结果是2,被打印出来。程序停留在yield 2,迭代器记住此时的执行的位置。
3、执行第三个next的时候,函数f()执行b = yield 2的赋值操作;print(b)打印为None;print('next');然后执行yield 3,返回给调用者,结果是3,被打印出来。程序停留在yield3,迭代次数已经用完,只有三个迭代器,迭代程序终止。
如果再次调用next的话,程序报错 StopIteration。print(c)是永远不会被执行的。
生成器-send()
send(num)作用:把里面的值传进到当前迭代器的yield位置,作为yield的返回值。同时触发一次迭代过程。
next(a) == a.send(None),next的效果等于send(None)
def f():
print('start')
a = yield 1
print(a)
print('middle....')
b = yield 2
print(b)
print('next')
c = yield 3
print(c)
a = f()
print(next(a))
print(a.send('msg'))
print(a.send('msg1'))
继续拿上面的例子来讲解,此时的执行结果如下:
start
1
msg
middle....
2
msg1
next
3
代码执行说明:
1、执行第一个next的时候,函数f()执行print('start'),然后执行yield 1,返回给调用者,结果是1,被打印出来。程序停留在yield 1,迭代器记住此时的执行的位置。
2、执行第二步a.send('msg')的时候,函数f() 执行 a = yield 1的赋值操作,此时yield是有返回值的,a是msg;执行print(a)打印结果为msg;执行print('middle....');然后执行yield 2,返回给调用者,结果是2,被打印出来。程序停留在yield 2,迭代器记住此时的执行的位置。
3、执行第三步a.send('msg1')的时候,函数f()执行b = yield 2的赋值操作,yield接受返回值msg1;print(b)打印为msg1;print('next');然后执行yield 3,返回给调用者,结果是3,被打印出来。程序停留在yield3,迭代次数已经用完,只有三个迭代器,迭代程序终止。
因为send都是会执行一次迭代过程,如果再次调用next或者send操作的话,程序报错 StopIteration。
send操作是往当前的迭代器yield位置返回参数,所以必须先调用next,如果程序第一次就用send的话,程序报错!
def f():
print('start')
a = yield 1
print(a)
print('middle....')
b = yield 2
print(b)
print('next')
c = yield 3
print(c)
a = f()
print(a.send('msg'))
TypeError: can't send non-None value to a just-started generator