python之迭代器与生成器
一、什么是迭代器
要说迭代器首先我们要先知道什么是迭代,迭代在计算机中是一种算法指的是让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。在python中迭代一般用于从一个数据对象中不断的取值,这种可以不断取值的属性就叫做iterable可迭代的,如何判断一个数据对象是否是可迭代的,只需要判断其是否含有内置函数__iter__,因为所有可迭代的对象都遵循可迭代协议即都含有__iter__方法。那么知道了迭代是什么,迭代器又是什么呢?迭代器是对可迭代对象取值优化的一种数据类型,它不像列表、元祖等可迭代对象是将所有元素全部存储在内存中,它是在被调用时才读取一个值到内存中,且迭代器只能从头到尾一个一个取值。
二、如何判断迭代器
判断一个对象是否是迭代器有以下两种方法:
1、'__iter__' in object and '__next__' in object
判断该对象中是否包含__iter__和__next__这两个方法,因为所有迭代器都遵循迭代器协议即每个迭代器中都包含__iter__、__next__两个方法
2、from collections import Iterator
print(isinstance(object,Iterator))
利用Iterator模块判断对象是否是迭代器,如果输出True则表示该对象是迭代器,输出False则表示该对象不是迭代器
三、获取迭代器
迭代器一般都是python内部使用的,我们如何获得一个迭代器对象呢?如果我们想要获取一个迭代器对象可以使用内置函数iter(),它可以把所有可迭代对象转成迭代器,另外map函数、filter函数也可以获得迭代器对象,打开文件获得的文件句柄也是一个迭代器对象
四、什么是生成器
生成器就是python提供的可以让程序员编写的迭代器,它具有迭代器的所有特性和内置函数
五、获取生成器
1、生成器函数
生成器函数的定义其实大部分和普通函数一样,只是生成器函数用yield代替了return来返回值,一个生成器函数的例子如下
1 def aver(): 2 total=0 3 day=0 4 avg=0 5 while True: 6 day_num=yield avg 7 total+=day_num 8 day+=1 9 avg=total/day 10 g=aver() 11 print(next(g)) 12 print(g.send(10)) 13 -------------------------------------------------------------------------------------- 14 0 15 10.0
生成器函数在被调用时只是返回给你一个生成器对象,并不会执行函数体中的代码,只有当你第一次使用next函数去取它的返回值时才开始执行函数体中的代码,然后当遇到yield时将返回值返回并将函数停止在那一步,这是可以使用send函数给yield传值,然后yield接收之后会继续执行之后的代码,此时生成器函数中需要有两个yield。值得注意的是生成器函数中不像普通函数一样,普通函数只能有一个return,但是生成器函数中可以有多个yield,并且多个yield是顺序执行的
2、生成器表达式
生成器表达式和列表推导式(列表解析)是类似的,只需要将列表推导式外面的[]中括号替换为()小括号即可。
1 #列表推导式范例 2 l=[i for i in range(10)] 3 print(l) 4 -------------------------------------------------------------------------------------- 5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 6 7 8 #列表生成式 9 l=(i for i in range(10)) 10 print(l) 11 -------------------------------------------------------------------------------------- 12 <generator object <genexpr> at 0x034657E0>
六、yield from
yield from是在python3中新加的语法,只是在生成器函数中简化循环的一种用法
七、生成器进阶示例
1 def demo(): 2 for i in range(4): 3 yield i 4 5 g=demo() 6 7 g1=(i for i in g) 8 g2=(i for i in g1) 9 10 print(list(g1)) 11 print(list(g2)) #生成器g中的值在上一次g1中被取完,所以g2取值时g中已经没有值 12 -------------------------------------------------------------------------------------- 13 [0, 1, 2, 3] 14 []
1 def add(n,i): 2 return n+i 3 def test(): 4 for i in range(4): 5 yield i 6 g=test() 7 for n in [1,10]: #整个for循环中生成器表达式g都没有取值,同时生成器表达式中的g被替换为test() 8 g=(add(n,i) for i in g) 9 print(list(g)) # =》(add(n,i) for i in (add(n,i) for i in g) ),n=10 10 -------------------------------------------------------------------------------------- 11 [20,21,22,23]
1 #普通的for循环 2 def f(): 3 for i in range(10): 4 yield i 5 g=f() 6 print(next(g)) 7 print(next(g)) 8 -------------------------------------------------------------------------------------- 9 0 10 1 11 12 13 #yield from简化的循环 14 def f(): 15 yield from range(10) 16 g=f() 17 print(next(g)) 18 print(next(g)) 19 -------------------------------------------------------------------------------------- 20 0 21 1

浙公网安备 33010602011771号