S7day14 迭代器与生成器

 

迭代器与生成器

1·迭代器

  迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。通俗讲某个数据集内的数据“一个挨着一个的值取出来”,就叫做迭代器。

  迭代是Python最强大的功能之一,是访问集合元素的一种方式。

  字符串列表元组字典集合文件句柄文件操作符range 都是可迭代的对象

1.1可迭代的对象 iterable (adj.可迭代的)

  我们在用for ... in ...语句循环时,in后面跟随的对象要求是可迭代对象,即可以直接作用于for循环的对象统称为可迭代对象(Iterable),如list、tuple、dict、set、str等

检验一个对象是否可迭代from collections import Iterable

示例:

from collections import Iterable
print(isinstance('aaa',Iterable)) #字符串
print(isinstance([1,2,3],Iterable))        #列表
print(isinstance((1,2,3),Iterable))        #元组

只要包含了“双下iter”方法的数据类型就是可迭代的对象 __iter__这个方法导致了一个数据类型的可迭代

print([1,2,3].__iter__())

数据类型和python解释器定下来的协议叫做可迭代的协议

1.2 迭代器 iterator(n.迭代器)

  可迭代对象是实现了__iter__()和__next__()方法的对象,可以显示地获取下一个元素。这种可以被next调用并不断返回下一个值的对象称为迭代器

检验一个对象是否是迭代器(from collections import Iterator)

from collections import Iterator
print(isinstance([1,2,3].__iter__(),Iterator))        #True
print(isinstance([1,2,3],Iterator))                   #Flase

迭代器遵循迭代器协议:必须拥有 __iter__ 和 __next__ 方法,迭代器一定是可迭代的对象,反过来不一定成立

lst_iterator = [1,2,3].__iter__()
print(lst_iterator.__next__())
print(lst_iterator.__next__())
print(lst_iterator.__next__())
#1
#2
#3

注意:1.使用__next__取值时,当取值超过取值对象的值时,会报错         StopIteration。

   2.取值时会按顺序依次取值,每值只取一次,不会多取也不会少取。

 

迭代器有两种:

1.天生就是迭代器,比如文件句柄(内部有__iter__)  

 

2.可迭代的对象 + __iter__

 

小结:

  ①可迭代对象

  可迭代的协议:含有__iter__方法的对象

  ②迭代器

  迭代的协议:含有__iter__ 和__next__方法

  ③迭代对象和迭代器的关系:

  迭代器包含迭代对象

  迭代器 = 迭代对象+__iter__      

二、生成器(Greator

  生成器(generator)就是一个能返回迭代器的函数,其实就是定义一个迭代算法,可以理解为一个特殊的迭代器。调用这个函数就得到一个迭代器,生成器中的yield相当于一个断点,执行到此返回一个值后暂停,从而实现next取值。

生成器的表达式,类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

①.能够对python中的基本数据类型进行统一的遍历,不需要关心每一个值分别是什么。

②.它可以节省内存 —— 惰性运算

  跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

例1:

def generator_func():              #生成器函数
    print(123)
    yield 'aaa'                    #return
g = generator_func()
ret = g.__next__()
print(ret)

#123
#aaa

  在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。

每个值只会调用一次,按顺序依次进行。

例2:

def generator_func():  #生成器函数
    print(123)
    yield 'aaa'   #return
    print(456)
    yield 'bbb'

g = generator_func()
ret = g.__next__()
print(ret)
ret2 = g.__next__()
print(ret2)

#123
#aaa
#456
#bbb

 小结

 1.带yield关键字的函数就是生成器函数 

 2.生成器函数在执行的时候只返回一个生成器,不执行生成器函数中的内容

 3.从生成器中取值

   ①.__next__ 有几个yield就可以取几次

   ②.for循环取值 正常取 for i in g:

   ③.其他数据类型进行强制转换 list(g) 返回一个列表,里面装着生成器中的所有内容

注意

  ①.调用生成器函数的时候,要先获取生成器,再进行next取值

  ②.生成器中的内容只能取一次,且按顺序取值没有回头路,取完为止

 

拓展资料

      可迭代对象 vs 迭代器 vs 生成器 的比较

 

posted @ 2017-09-04 17:35  panda_R  阅读(96)  评论(0)    收藏  举报