背景:
在python中,有很多对象都可以通过for循环来对其中的每一个元素进行访问,比如list、dict、string等,这些对象被称为可迭代对象。
什么是迭代器
迭代器(Iterator)是访问集合内元素的一种方式,提供了一种遍历序列对象的方法。用来迭代操作对象,可以像列表一样,迭代的获取其中的每一个元素,任何实现了__next__方法的对象,都可以称之为迭代器。
迭代器的特点
__iter__方法返回迭代器本身;
next()方法返回容器的下一个元素
当没有下一个元素时,会报出StopIteration异常
与列表的区别
构建迭代器的时候,不需要像列表一样,把所有的元素一次性加载到内存,而是通过使用延迟计算(lazy evaluation)的方式返回元素,这是迭代器的优点之一。
举例:如果一个列表包含一千万个整数,需要占用400M的内存,如果使用迭代器,只需要几十字节的内存。因为迭代器没有把所有元素加载到内存,而是调用迭代器的next方法时才返回该元素。
迭代器的例子
- alist = [1,2,3,4]
- it = iter(alist)
这里创建了一个列表,然后使用了iter()方法实现了迭代器。
打印看一下是不是迭代器类型:
print(it)
<list_iterator object at 0x00000219B162C8E0>
那么如何遍历迭代器里面的元素呢,下面是一些方法。
当我们使用next()方法时,会按顺序返回迭代器中的元素,比如第一次调用next方法,返回列表中的元素1,第二次调用next方法,会返回列表中第二个元素2。
- print(next(it))
- print(next(it))
- 1
- 2
那么如何遍历所有的元素呢,每一次都用next不太现实,这里就要用到循环,第一种方式while循环:
- while True:
- try:
- print(next((it)))
- except StopIteration:
- break
- 1
- 2
- 3
- 4
注意,这里用while(True)不断的取出迭代器中的元素,但是当超出范围时,会报出StopIteration异常,所以这里用Try-expect来捕获异常。
第二种方式:利用for循环
- for item in it:
- print(item)
直接利用for-in结构,取出迭代器中的每一个元素,然后输出,很明显比上面一种方法简洁很多。
如果需要在遍历的同时取出元素的索引值,只需要使用enumerate即可,和一般的列表之类的遍历相同:
- for index,item in enumerate(it):
- print(index,item)
接下来让我们自己编写一个迭代器的类
- class Fib:
- def __init__(self,n):
- self.prev = 0
- self.cur = 1
- self.n = n
- print(self.n)
- def __iter__(self):
- return self
- def __next__(self):
- if self.n>0:
- value = self.cur
- self.cur = self.cur + self.prev
- self.prev = value
- self.n-=1
- return value
- else:
- raise StopIteration()
- f = Fib(10)
- for item in f:
- print(item)