生成器和迭代器
迭代器-Iterator
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
可迭代对象:
以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
一类是 generator (下面),包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。
凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型
集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象
生成式
1.列表生成式
list = [i*2 for i in range(5)] list
out:[0,2,4,6,8]
生成的list为[0,2,4,6,8]
2.元组生成式
tuple = (i*2 for i in range(5)) tuple
out:<generator object <genexpr> at 0x000002308A3ADFC0>
结果并没有生成一个元组,而是一个生成器。
生成器-generator
利用列表生成式,我们可以直接创建一个列表。但是,列表中的所有元素都被存放在了内存中,占用了大量内存空间。为了节省内存,在python中,如果列表元素可以按照某种算法推算出来,那我们就不必创建完整的list。这种一边循环一边计算的机制,称为生成器(generator)。比如:元组生成式。
tuple = (i*2 for i in range(5)) next(tuple) out:0 next(tuple) out:2
生成器可以通过next()方法计算下一个元素的值。
for i in tuple: print(i) out:0 2 4 6 8
也可以通过for循环取值,因为生成器是可迭代的。
生成器函数
含有yield关键字的成为生成器函数,yield作用和return类似,把yield后面的内容返回,但一个函数可以有多个yield。
def generator(): print('1') yield 'a' print('2') yield 'b' yield 'c' g = genarator() #得到一个生成器g ret = g.__next__() print(ret) ret = g.__next__() print(ret) ret = g.__next__() print(ret)
每执行一次g.__next__(),函数会停止在yield,并把内容返回。
也可以用for循环一次性执行
for i in g: print(i)
效果与上面相同。
send方法
#生成器的send用法 generator.send(value) def test(): i = 1 while i < 5: temp = yield i**2 print(temp) i += 1 t = test() #第一次运行只能使用next或者send(None) print(t.__next__()) #send的作用相当于使生成器继续运行,并且传递的参数为yield的返回值(程序中即temp的值) print(t.send("Hello World")) print(t.__next__())#相当于send(None) 此时temp = None