迭代:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来
while True: print('=------->') l=[1,2,3,4,5,6] n=0 while n < len(l): print(l[n]) n+=1
这个循环就是每次重复都是基于上一次的结果而来。
2、要想了解迭代器到底是什么,就必须先了解一个概念。即什么是可迭代的对象?
可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代对象
以下都是可迭代的对象 它们的内置中都有__iter__方法。
字符串: str='hello' 列表: list=[1,2,3] 元组: tup1=(1,2,3) 字典: dic={'x':1} 集合: s1={'a','b','c'} 文件: f=open('a.txt','w',encoding='utf-8')
用法如下:
dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
3、迭代器对象:迭代取值工具,可迭代的对象执行__iter__方法得到的返回值就是迭代器对象。
以下是迭代器对象。
特点是他们都带有__next__的方法。
列表 list1=[1,2,3]
字典 dic={'x':1,'y':2,'z':3} 集合 s1={'a','b','c'}
如下:
dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
iter_dic.__next__())
4、可迭代的对象VS 迭代器对象?
可迭代的对象:str, list, tuple, dic, set, file
1、获取可迭代对象的方式:无须获取,python内置:str, list, tuple, dic, set, file都是可迭代对象。
2、特点:
内置__iter__方法都叫可迭代的对象,执行该方法会拿到一个迭代器对象
迭代器对象:文件对象本身就是迭代器对象
1、获取迭代器对象的方式:
执行可迭代对象的__iter__的方法,拿到的返回值就是迭代器对象
2:特点:
内置有__next__方法,该执行方法会拿到迭代器对象中的一个值
内置有__iter__方法,执行该方法会拿到迭代器本身
迭代器的优缺点
1、迭代器的优点
1、提供了一种可以不依赖于索引的取值方式
l=open('a.txt','r',encoding='utf-8') iter_l=l.__iter__() while True: try: print(iter_l.__next__()) except StopIteration: break
2、迭代器更加节省内存
同样 有优点 就有缺点,
缺点1:取值麻烦,只能一个一个取,只能往后取,
缺点2:并且是一次性,无法用len获取长度。
3、for 循环原理分析:
1:for循环称之为迭代器循环,in后跟的必须是可迭代的对象:
2:for循环会执行in后对象的__iter__方法,拿到迭代器对象。
3:然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体。
4:周而复始,直到取值完毕, for循环会检测到异常自动结束循环。
生成器:
函数内包yield 关键字,
再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
def chicken(): print('=====>first') yield 1 #保函 yield,到这个yield后暂停不动,这个1就是返回值,也是 生成器的对象 print('=====>sencond') yield 2 print('=====>third') yield 3 obj=chicken()
生成器的本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法。
所以他的循环也是遵循迭代器用法
def chicken(): print('=====>first') yield 1 print('=====>sencond') yield 2 print('=====>third') yield 3 obj=chicken() for item in obj: print(item) #打印结果: =====>first 1 =====>sencond 2 =====>third 3 #第一步 iter_obj=obj.__iter__(),拿到迭代器, 第2步;出发iter_obj._next_(),拿到该方法的返回值,赋值给item, 第3步 周而复始,直到函数内不再有yield,即取值完毕。 第4步,for会检测导StopIteration异常,结束循环。
总结yield:
1:为我们提供了一种自定义迭代器的方式,
可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器。
2:yield可以让return一样用于返回值,区别是return值能返回一次值,变结束,二yield可以返回多次值,因为yield可以保存函数的执行的状态。
def my_range(): print('start.......') n=0 while True: yield n n+=1 obj =my_range() print(obj) for i in my_range(): print(i) #打印结果 1 2 3 4 5 6 7 8 。 。 。 。 。 。 一直到无穷大。就是因为yield只是暂停。
3、生成器yield的表达形式:
第一步、必须初始化一次, 让函数停在yield的位置,
第二部:然后在send给yield传值, send有两个作用, 一个给yield传值,一个是当__next__的功能使用。
def eat(name): print('%s ready to eat'%name) food_list=[] while True: food =yield food_list.append(food) print('%s start to %s'%(name,food)) dog1=eat('alex') res0=dog1.__next__() #第一次 先调用__next__(),让函数停在这里 # print(res0) res1=dog1.send('肉') #然后send给yield传值。 #打印结果 alex ready to eat alex start to 肉 ['肉'] alex start to 麻辣烫 ['肉', '麻辣烫']