pyhton迭代器及生成器 最后更新时间:2021年03月02日 ## 迭代器 ### 迭代器介绍 迭代器指的是迭代取值的工具,迭代是指一个重复的过程,每一次重复都是基于上一次结果而来迭代提供了一种通用的不依赖索引的迭代取值方法。 ### 可迭代对象 可以用 for循环遍历的对象都是可迭代对象。 - str,list,tuple,dict,set 等都是可迭代对象。 - generator (生成器 和 yield 的生成器函数) 也是可迭代对象。 ### 判断是否可迭代 - 是否有内置的__iter__方法 - `isinstance(obj, Iterable)` 示例: ```python from collections import Iterable num = [1,2,3,4] print(isinstance(num, Iterable)) # ==> 返回值为true,list可迭代。 name = "kirito" print(isinstance(name, Iterable)) # ==> 返回值为true,str可迭代。 n = 123 print(isinstance(n, Iterable)) # ==> 返回值为false,int不可迭代。 ``` ### 迭代器 - 有内置的__iter__()方法的对象,执行迭代器的__iter__()方法得到的依然是迭代器本身。 - 有内置的__next__()方法的对象,执行该方法可以不依赖索引取值。 - 可迭代对象不一定是迭代器。 示例: ```python from collections import Iterator li=[1,2,3,4] print(isinstance(li, Iterator)) # ==> 返回值为false,list不是迭代器。 ``` ### iter() 可以被 next() 函数调用并不断返回下一个值的对象称为迭代器:Iterator。那我们可 以通过 iter() 方法将可迭代的对象,转为迭代器。 示例: ```python num = [1,2,3,4] nums = iter(num) nums.__next__() # ==> 返回nums中的第一个元素,接下来再使用__next__(),则依次返回接下来的元素。 next(nums) # ==> 效果同__next__() ``` #### 注意: - 迭代器不可以通过下标取值,而是使用 __next__() 或者 next() 。但是只要超出范围则直接报错StopIteration 。 - next() 只能顺延调用,不能往前。(不可以逆着取) ### 可迭代对象与迭代器区别 - 可用于 for 循环的都是可迭代类型。 - 作用于 next() 都是迭代器类型。 - list、dict、str 等都是可迭代的但不是迭代器,因为 next() 函数无法调用它们。可以通过 iter() 函数将它们转为迭代器。 - python 的 for 循环本质就是通过不断调用next()函数实现的。 ## 生成器 ### 生成器定义 在Python中,一边循环一边计算的机制,称为生成器:generator。 生成器在循环的过程中根据算法不断推算出后续的元素,因此不会创建一个完整的列表,从而节省了大量的内存空间。 ### 生成器表达式 `(ele_exp for element in iterable)` 生成器表达式来源于迭代和列表解析的组合,生成器和列表解析(即列表推导式)类似,但是它使用 () 而不是 []。 示例: ```python test = (i for i in range(10)) print(test.__next__()) # ==> 返回值为0 print(test.__next__()) # ==> 返回值为1 print(test.__next__()) # ==> 返回值为2 ``` ### 生成器函数( yield ) 当一个函数中包含 yield 关键字,那么这个函数就不再是一个普通的函数,而是一个 generator (即生成器)。 调用函数就是创建了一个生成器对象。其工作原理就是通过重复调用 next() 或者 __next__() 方法,直到捕获一个异常。 示例: ```python def test(num): n=0 while n 返回值为0 print(t.__next__()) # ==> 返回值为1 print(t.__next__()) # ==> 返回值为2 ``` ### 注意: yield返回一个值,并且记住这个返回值的位置,下次遇到 next() 调用时,代码从yield 的下一条语句开始执行。与 return 的差别是,return 也是返回一个值,但是直接结束函数。 ### send(): send() 和 next() 一样,都能让生成器继续往下走一步(遇到 yield 返回),但 send() 能传一个值,这个值作为 yield 表达式整体的结果。 示例: ```python def test(): b = yield "holle" a = "hi" yield a yield b t=test() print(next(t)) print(t.send("world")) print(next(t)) # 返回值为: # ==> holle # ==> hi # ==> world ```
Comments | NOTHING