迭代器: 定义:更新换代的过程 每次迭代都必须基于上一次的的结果 器:迭代取值的工具 特色:不依赖索引取值 迭代取值的数据类型:字符串,列表,元组,字典,集合 一,可迭代对象 1,可迭代对象:只有内置有__iter__方法的都叫作可迭代对象 2,是可迭代对象的有: str list tuple dict set 文件对象(执行内置的__iter__以后仍是自己 没有任何变化) 文件对象自己就是迭代器对象 案例: res = s.__iter__() # res = iter(s) print(s.__len__()) # 简化成了len(s) res1 = l.__iter__() # res1 = iter(l) res2 = f1.__iter__() # res2 = iter(f1) 重点:可迭代对象执行内置的__iter__方法获得就是该对象的迭代器对象 二:迭代器对象 1,内置有__iter__方法 2,内置有__next__方法 (进行取值) 注意:迭代器对象必定是可迭代对象 而可迭代对象不必定是迭代器对象 必须知足1,2 两个条件才是迭代器对象 1》生成一个可迭代对象 l = [1,2] res = l.__iter__() # 就是把一个可迭代对象用.__iter__()方法生成迭代器对象 2》迭代器取值 调用 __next__() print(res.__next__()) # 1 # 调用依次取出一个元素(迭代器对象中有几个元素就能够调用几回) 直到取完,就会报错StopIteration 案列: f1 = open('xxx.txt','r',encoding='utf-8') 调用f1内置的__iter__方法 iter_f = f1.__iter__() print(iter_f is f1) # 判断iter_f 是否是 f1 ,打印 True 或者 False 重点:1,迭代器对象的取值必须用 __next__() 2,迭代器对象不管执行多少次__iter__方法,获得的仍是迭代器对象自己 # print(f1 is f1.__iter__().__iter__().__iter__().__iter__()) 3. 迭代器取值的特色: 只能日后依次取值,不能倒着取 **注意:4,可迭代对象转为迭代对象用一次 .__iter__() 就可,屡次调用和第一次调用同样(能够理解为初始化) 5,调用一次.__next__()方法只能取出其中一个元素,(列表为第一个值,字典取出的是key) 总结: 可迭代对象:内置有__iter__方法的 迭代器对象: 既 内置有__iter__ 也内置有__next__方法 迭代取值:优势:不依赖索引取值 内存中始终都占一份空间,不会致使内存溢出 缺点 1.不可以获取指定的元素,只能从前日后依次取 2.取完以后会报StopIteration错 案例:1,文件取值案列 (假如文件中有一行内容,若是有n行就调用n次iter_f.__next__() f = open('xxx.txt','r',encoding='utf-8') iter_f = f.__iter__() print(iter_f.__next__()) 2,可迭代对象取值(list,dict,set,tuple,str) l = [1,2,3,4] iter_l = l.__iter__() print(iter_l.__next__()) # 1 l2 = {'name':'jason'} iter_l2 = l2.__iter__() print(iter_l2.__next__()) # name l3 = (3,'sr',[1,2],{1,'sc'}) iter_l3 = l3.__iter__() print(iter_l3.__next__()) # 3 print(iter_l3.__next__()) # sr print(iter_l3.__next__()) # [1, 2] print(iter_l3.__next__()) # {1, 'sc'} 其中的元素是什么类型,取出来的也是该数据类型 三:for循环的本质: for i in d: # for循环后面的in关键 跟的是一个可迭代对象 1.将in后面的对象调用__iter__转换成迭代器对象 2.调用__next__迭代取值 3.内部有异常捕获StopIteration,当__next__报这个错 自动结束循环 四:生成器: 用户自定义的迭代器,本质就是迭代器 1,函数内有yield关键字存在时,函数名加括号不会运行函数体的代码块 而是将它转变为生成器,当用.__next__() 方法时才会走函数体代码 2,函数体代码运行遇到yield 就会暂停运行 3,yield后面跟的值就是调用迭代器__next__方法你能获得的值 ******** 4, yield既能够返回一个值也能够返回多个值 而且多个值也是按照元组的形式返回 5,yield 支持外界为其传参,多个值时 是以元组的形式返回 案列: def func(): print('egon not is dsb') yield 'no' print('天上飞来一只猴') yield '666' g = func() # 生成器初始化:将函数变成迭代器 g.__next__() ## egon not is dsb print(g.__next__()) #天上飞来一只猴 666 注意:函数体代码中有 yield,当函数名加括号调用时, 他就是将函数转变为了自定义的生成器,并不会当即执行函数体代码 案列: def func(name): print('%s 准备开吃'%name) while True: food = yield print('%s 吃了 %s'%(name,food)) g = func('egon') g.__next__() # 必须先将代码运行至yield 才可以为其传值 #egon 准备开吃 g.send('每天向上') # 给yield左边的变量传参 触发了__next__方法 # egon 吃了 每天向上 g.send('好好学习') #egon 吃了 好好学习 2,生成器表达式: res = (i for i in range(1,100000000) if i != 4) # 生成器表达式 print(res) 1,生成器不会主动执行任何一行代码 2,必须经过__next__触发代码的运行zcf 四:内置函数 divmod 分页器 print(divmod(101,10) enumerate 枚举 exec(s) eval(s) eval不支持逻辑代码 format 三种玩法 {}占位 {index} 索引 {name} 指名道姓 isinstance 后面统一改方法判断对象是否属于某个数据类型 n = 1 print(type(n)) print(isinstance(n,list)) # 判断对象是否属于某个数据类型 l = [0,1,0] print(all(l)) # 只要有一个为False就返回False print(any(l)) # 只要有一个位True就返回True补充: 异常处理: while True: try: print(iter_d.__next__()) except StopIteration: print( ’取完了,没有了') break