python3 迭代器和生成器是什么?
迭代器就是可迭代对象 生成器就是可迭代对象 什么是迭代器协议: ? 1、迭代器协议:对象必须提供一个next()方法(和__next__方法功能一样),执行该方法要么返回迭代中的下一下,要么引起一个Stopiteration异常,终止迭代(只能向后走,不能往前看) ? 2、.可迭代对象:实现了迭代器协议的对象(特征:对象内部定义一个__iter__()方法) ? 3、协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。 for循环的本质: ? 循环对象,都是使用迭代器协议: 代码验证: #?下标访问方式???仅适用str,?list,?tuple,不适用set,dict?因为这是无序的 li?=?[1,?2,?3] print(li[0]) print(li[1]) print(li[2]) print(li[3]) 结果:1,2,3,??报错:IndexError:?list?index?out?of?range #?遵循迭代器协议访问方式 li?=?[1,?3] iterator_li?=?li.__iter__() print(iterator_li.__next__()) print(iterator_li.__next__()) print(iterator_li.__next__()) print(iterator_li.__next__()) 结果:1,??报错:IndexError:?StopIteration #?for循环访问方式 #?for循环本质就是遵循迭代器协议的访问方式,先调用iterator_li=l.__iter__()方法,或者直接iterator_li=iter(li),然后依次执行 iterator_li.__next__(),直到for循环捕捉到StopIteration终止循环 for?i?in?li:????#?iterator_li=l.__iter__()方法?或者? ????print(i)????#?i?=?iterator_li.__next__()?并且捕捉StopIteration错误,结束循环 ???? #?while模拟for循环 iterator_li?=?iter(li) while?True: ????try: ????????print(iterator_li.__next__()) ????except?StopIteration: ????????print('迭代完毕,结束运行') ????????break 注意: (字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象,然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代。 序列类型字符串,列表,元组都有下标,可以直接使用for循环+下标模式达到迭代器效果。但是非序列类型字典、集合、文件等是无序,想要实现迭代,必须要遵循迭代器协议 什么是生成器: ? 生成器可以理解为一种数据类型,这种数据类型自动实现迭代器协议(其他数据类型需要调用内置__iter__()方法),所以生成器就是迭代器。 生成器在python中的表现形式: ? 1、生成器函数 ? ?常规函数定义,唯一一点不同的是使用yield语句替换return语句返回结果,yield语句一次返回一个结果,在每个结果之间,挂起函数状态,以便下次重新运行。(yield语句,在函数中并不是像return,执行return就结束函数运行;而是可以执行多次后结束。) ? 2、生成器表达式 ? 类似列表推导式(列表解析式),但是生成器返回的不是一个一次构建的结果列表,而是一个对象。 生成器函数: def?test(): ????yield?1 ????yield?2 gen?=?test() print(gen.__next__()) print(gen.__next__()) 1 2 生成器表达式: ????1、把列表解析的[] 换成 () 得到就是生成器表达式。 ????2、生成器表达式更加节省内存 示例: egg?=?('猪{}'.format(i)?for?i?in?range(1,?10)?if?i?>?5) print(egg.__next__()) print(egg.__next__()) 猪6 猪7 sum示例: print(sum(i?for?i?in?range(100)))??#?sum()?使用生成器可以不用再加多一个括号 4950 生成器小结: ? 1、生成器是可迭代对象 ? 2、实现延迟计算,节省内存 ? 3、生成器本质和其他数据类型一样,都是实现了迭代器协议,只不过生成器附加一个延迟计算一次返回一个结果,节省内存的好处,其他可迭代对象不具有这特征。 生成器注意事项: ? 1、生成器只能遍历一次,第二次遍历会直接报‘StopIteration’错误 生成器总结: ? 1、语法和函数类似。????差别在于生成器使用yield语句返回一个值,而常规函数使用return返回一个值 ? 2、自动实现迭代器协议????生成器在没有值可以返回的时候,产生Stopiteraton异常 ? 3、状态挂起????生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |