关于迭代器的一些总结

在进行for循环的时候,会碰到两个名词:一个是可迭代的对象iterable,一个是迭代器iterator。


可迭代的对象有很多,例如sequence中的string,list,tuple,还有字典dict,文件file等,在可迭代的对象中,主要是实现了__iter__()方法,从而使可迭代的。


迭代器iterator,在其中主要实现了方法__iter__()方法,和next()方法,所谓的迭代器也就是指具有next()方法的对象。在迭代器中的__iter__方法返回了一个可迭代的对象,当一个迭代器具有next方法的时候,那么就可以返回其自身,也就是return self。


可迭代的对象,也可以理解为可以使用for进行循环的对象。


迭代器是一个对象,迭代器的限制在于不能进行复制,不能从头开始。


判断一个类型是否是可以迭代的,可以使用isinstance方法,如下所示:

>>> from collections import Iterable
>>> isinstance(list(),Iterable)
True
>>> isinstance('kel',Iterable)
True
>>> isinstance(tuple(),Iterable)
True
>>> isinstance(dict(),Iterable)
True

创建迭代器主要使用以下方法:

iter(obj)
在进行创建的时候,会查看obj是否是可迭代的,如果是可迭代的,那么将返回一个迭代器。


迭代的过程如下:

使用for循环来进行遍历——》根据next得到下一个值——》到达最后的时候触发异常Stopiteration——》for循环捕获异常——》循环结束


在迭代器中,只能够迭代一次,而在可迭代对象中,可以无限迭代,从而可以将数据和迭代进行分离,将数据保存在一个地方,将迭代器保存在另外一个地方,从而形成无限迭代,如下所示:

class Data(object): #用来保存数据的类
    def __init__(self,*args):
        self.data = tuple(args)
    def __iter__(self): #可迭代的主要实现方法__iter__(self)方法
        return DataIterable(self)

class DataIterable(object): #迭代器的类
    def __init__(self,data):
        self.data = data.data #注意初始化的时候,传递是是一个Data的实例,从而需要得到data的属性
        self.index = 0
    def __iter__(self): #迭代器直接返回自身,也就是返回具有next函数的迭代器的类
        return self
    def next(self): #迭代器的主要方法next,不具有参数
        if self.index == len(self.data): #遍历完所有的数据之后,抛出StopIteration的异常
            raise StopIteration
        else:
            data = self.data[self.index]
            self.index += 1
            return data
if __name__ == '__main__':
    data = Data(1,'kel','xyz',4.56)
    for values in data:  #可以进行无限迭代
        print values
    for values in data: #第二次迭代
        print values


内建的迭代器的函数:

1、 reversed()返回一个倒序的可迭代的对象

2、 enumerate()返回一个带有下标的迭代器

3、any()返回真当任何一个bool(x)为真

4、 all()返回真当所有的bool(x)为真


迭代器的真正好处在于只有在for循环的时候才计算得到的值,例如range函数和xrange函数:

>>> from collections import Iterable
>>> isinstance(range(1),Iterable)
True
>>> isinstance(range(1),list)
True
>>> isinstance(xrange(1),Iterable)
True
>>> isinstance(xrange(1),list)
False
>>> range(10) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> xrange(10)
xrange(10 
以上表示,range生成的是一个列表,而xrange则是一个迭代器,从而在使用for循环的时候,range占用大量的内存,而xrange则是在循环的时候才得到值,从而比较节省内存,如下所示:

>>> import sys
>>> sys.getsizeof(range(10000))
80072
>>> sys.getsizeof(xrange(10000)) #可以看到xrange占用的内存很小,从而使用迭代器更加具有效率
40




posted @ 2016-04-03 21:06  KEL  阅读(479)  评论(0编辑  收藏  举报