python进阶之 ——迭代器与生成器
一、迭代器
1.什么是迭代器
迭代:一个重复的过程,但每次重复都是基于上一次重复的结果而继续
迭代器就是迭代取值的工具
2.为什么要用迭代器
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
优点:
I.其可以提供一种不依赖索引的迭代取值方式
II.更节省内存
缺点:
I.不如按照索引的取值方式灵活
II.其为取值一次性的,只能向后取,无法预测值的个数
可迭代对象:内置有__iter__方法的对象,即obj.__iter__(str\list\tuple\dict\set\文件对象)
迭代器对象:既内置有__iter__方法又内置有__next__方法的对象,即open('a.txt').__iter__(文件对象)
迭代器对象为可迭代对象执行obj.__iter__()得到的结果
调用可迭代对象下__iter__方法,会有一个返回值,该返回值就是内置的迭代器对象
迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象
3.如何用
dic={'a':1,'b':2,'c':3} iter_dic=dic.__iter__() #得到迭代器对象,迭代器.__iter__()得到的仍然是迭代器本身 iter_d=iter(d) #其相当于d.__iter__ print(iter_dic.__next__()) #《==》next(iter_dic) # 需注意,当next次数超过key次数时,会抛出StopIteration结束标志 while True: try: v=iter_d.__next__() print(v) except StopIteration: break #a b c
dic={'a':1,'b':2,'c':3} for k in dic: print(dic[k]) # 1 2 3
for循环的底层原理
1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
2: 执行iter_obj.__next__()即next(iter_dic),将得到的值赋值给k,然后执行循环体代码
3: 重复过程2,直到捕捉到异常StopIteration,结束循环
二、生成器:一种自定义的迭代器
1.如何得到
函数内出现yield关键字,再去调用函数不会立即执行函数体代码,会得到一个返回值,该返回值就是生成器对象,即自定义的迭代器
def func(): print('first') yield 1 print('second') yield 2 print('third') yield 3 g=func() print(g) # <generator object func at 0x0000025FB008FE08> res1=next(g) # first print(res1) # 1 res2=next(g) # second print(res2) # 2 res3=next(g) # third print(res3) # 3 next(g) # StopIteration
yield:
1.提供一种自定义迭代器的解决方案
2.yield & return
相同:都可以返回值,返回值没有类型/个数限制
不同:return只能返回一次值,yield却可以让函数暂停在某一个位置,可以返回多次值