Python迭代器笔记

python中的三大器有迭代器,生成器,装饰器,本文重点讲解下迭代器的概念,使用,自定义迭代器等的介绍。

1.概念:

  迭代器是一个对象,一个可以记住遍历位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束,迭代器只能往前,不能后退,实质是具备了__next__和__iter__方法的对象

2.可迭代对象:

  可以通过for in 等类似操作进行遍历取值的对象,本质是具备了__iter__方法的对象,因为__iter__方法提供了迭代器,实现了遍历位置的记录。在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。

3.代码实现:

3.1通过isinstance()判断

In [1]: from collections import Iterable

In [2]: isinstance({},Iterable)
Out[2]: True

In [3]: isinstance((),Iterable)
Out[3]: True

In [4]: isinstance("",Iterable)
Out[4]: True

In [5]: for item in {}:
   ...:     pass
   ...: 

In [6]: for item in "":
   ...:     pass
   ...: 

In [7]: for item in ():
   ...:     pass
   ...: 

3.2 for in的本质

就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。

li = [100, 200, 300, 400]
# for num in li:
#     print(num)


# 1. 通过调用可迭代对象的__iter__()获取迭代器
# 2. 对迭代器调用__next__进行迭代操作,
#     如果没有抛出StopIteration异常,表示迭代没有结束,把获取到的数据元素放到变量中
#     如果抛出了异常,表示迭代结束,退出执行
# 3. 执行循环体
# 4. 跳转到第2步执行

iterator = li.__iter__()

while True:
    try:
        num = iterator.__next__()
    except StopIteration:
        break
    else:
        print(num)

3.3 自定义迭代器

class MyIterable(object):
    def __init__(self):
        self.container = [] # 定义一个容器

    def add(self, item):
        self.container.append(item)

    def __iter__(self):
        return Iterator(self.container) # 返回一个迭代器


class Iterator(object):
    def __init__(self, container):
        self.container = container
        self.i = 0

    def __next__(self):
        if self.i < len(self.container):
            count = self.i
            self.i += 1
            return self.container[count]
        else:
            raise StopIteration

    def __iter__(self):
        pass


mi = MyIterable()
it = mi.__iter__()
mi.add(1)
mi.add(2)
mi.add(3)

for item in mi:
    print(item)

from collections import Iterator

print(isinstance(it, Iterator))

3.4 合并迭代器

Python要求定义的迭代器必须实现__iter__(self),并且返回self。通常,一个可迭代对象的迭代器都是固定的,并且,类与类之间需要距离性,对象之间需要相似性,所以通常可迭代对象和迭代器写在一起,就是下面的。

class MyIterable(object):
    def __init__(self):
        self.container = []
        self.i = 0

    def add(self, item):
        self.container.append(item)

    def __next__(self):
        if self.i < len(self.container):
            count = self.i
            self.i += 1
            return self.container[count]
        else:
            raise StopIteration

    def __iter__(self):
        return self


mi = MyIterable()
mi.add(1)
mi.add(2)
mi.add(3)

for item in mi:
    print(item)

 3.5 迭代器应用场景之实现菲波那切数列

  我们发现迭代器最核心的功能就是可以通过next()函数的调用来返回下一个数据值。如果每次返回的数据值不是在一个已有的数据集合中读取的,而是通过程序按照一定的规律计算生成的,那么也就意味着可以不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来供后续依次读取,这样可以节省大量的存储(内存)空间。

class Fib(object):
    def __init__(self, num):
        self.num = num
        self.num1 = 0
        self.num2 = 1
        self.i = 0

    def __next__(self):
        if self.i < self.num:
            self.i += 1
            temp = self.num1
            self.num1, self.num2 = self.num2, self.num1 + self.num2
            return temp
        else:
            raise StopIteration

    def __iter__(self):
        return self


fib = Fib(7)
print(list(fib))

 4.iter()函数与next()函数

对于可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的__iter__方法。

>> li = [1,2,3]
>>> li_iter = iter(li)
>>> next(li_iter)
1
>>> next(li_iter)
2
>>> next(li_iter)
3
>>> next(li_iter)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

 

posted @ 2016-09-04 15:50  GreatAnt  阅读(1335)  评论(0编辑  收藏  举报