可迭代的对象与迭代器详解

发布于 2018-09-11 05:36:46

可迭代的对象

使用iter内置函数可以获取迭代器的对象。如果对象实现了能返回迭代器的iter方法,那么对象就是可迭代的。序列都可以迭代;实现了getitem方法,而且其参数是从零开始的索引,这种对象也可以迭代。

class IterObj(object):
    """
    [1,2] => (1,2)
    [1,2,3] => (1,2),(3,None)
    """
    def __init__(self, l):
        if len(l)%2:
            l.append(None)
        self.l = l

    def __iter__(self):
        # 返回生成器
        return ((self.l[i], self.l[i+1]) for i in range(0, len(self.l), 2))

if __name__ == '__main__':
    # 该对象可以迭代但是并不是迭代器
    t = IterObj([1, 2, 3])
    # 执行next操作会报错
    # next(t)
    # Traceback (most recent call last):
    #     File ".\iter_obj.py", line 19, in <module>
    #         next(t)
    # TypeError: 'IterObj' object is not an iterator
    # 但是可以执行for操作
    # for i in t:
    #     print(i)
    # (1, 2)
    # (3, None)
    # 可迭代的对象可以通过iter转换为迭代器
    # iter(t)

迭代器

迭代器是这样的对象:实现了无参数的next方法,返回序列中的下一个元素;如果没有元素了,那么抛出StopIteration异常。Python中的迭代器还实现了iter方法,因此迭代器也可以迭代。

class Iterator(object):
    """
    [1,2] => (1,2)
    [1,2,3] => (1,2),(3,None)
    """
    def __init__(self, l):
        if len(l)%2:
            l.append(None)
        self.l = l
        self.index = 0

    def __iter__(self):
        # 返回生成器
        return self

    def __next__(self):
        try:
            return (self.l[self.index], self.l[self.index+1])
        except IndexError:
            raise StopIteration()
        finally:
            self.index += 2

if __name__ == '__main__':
    # 该对象是迭代器
    iterator = Iterator([1, 2, 3])
    # for i in iterator:
    #     print(i) 
    # print(next(iterator))
    # print(next(iterator))

可迭代的对象和迭代器的关系

可迭代的对象有个iter方法,每次都实例化一个新的迭代器;而迭代器要实现next方法,返回单个元素,此外还要实现iter方法,返回迭代器本身。

因此,迭代器可以迭代,但是可迭代的对象不是迭代器。