1.背景

在python中,有很多对象都可以通过for循环来对其中的每一个元素进行访问,比如list、dict、string等,这些对象被称为可迭代对象。

2.什么是迭代器

迭代器(Iterator)是访问集合内元素的一种方式,提供了一种遍历序列对象的方法。用来迭代操作对象,可以像列表一样,迭代的获取其中的每一个元素,任何实现了__next__方法的对象,都可以称之为迭代器。

3.迭代器的特点

__iter__()方法返回迭代器本身
next()方法返回容器的下一个元素
当没有下一个元素时,会报出StopIteration异常

4.与列表的区别

构建迭代器的时候,不需要像列表一样,把所有的元素一次性加载到内存,而是通过使用延迟计算(lazy evaluation)的方式返回元素,这是迭代器的优点之一。
举例:如果一个列表包含一千万个整数,需要占用400M的内存,如果使用迭代器,只需要几十字节的内存。因为迭代器没有把所有元素加载到内存,而是调用迭代器的next()方法时才返回该元素。

5.迭代器的例子

alist = [1,2,3,4,5,6,7,8,9]
it = iter(alist)

这里创建了一个列表,然后使用了iter()方法实现了迭代器。
打印看一下是不是迭代器类型

print(it)
<list_iterator object at 0x000002903BE35278>

那么如何遍历迭代器里面的元素呢,下面是一些方法。

当我们使用next()方法时,会按顺序返回迭代器中的元素,比如第一次调用next()方法,返回列表中的元素1,第二次调用next()方法,会返回列表中第二个元素2。

print(next(it))
print(next(it))
print(next(it))
1
2
3

那么如何遍历所有的元素呢,每一次都用next()不太现实,这里就要用到循环,第一种方式while循环:

while True:
    try:
        print(next(it))
    except StopIteration:
        break
1
2
3
4
5
6
7
8
9

注意,这里用while True不断地取出迭代器中的元素,但是当超出范围时,会报出StopIteration异常,所以这里用Try-expect来捕获异常。

第二种方式:利用for循环

for item in it:
    print(item)
1
2
3
4
5
6
7
8
9

直接利用for-in结构,取出迭代器中的每一个元素,然后输出,很明显比上面一种方法简洁很多。

如果需要在遍历的同时取出元素的索引值,只需要使用enumerate()即可,和一般的列表之类的遍历相同:

for index,item in enumerate(it):
    print(index,item)
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9

接下来让我们自己编写一个迭代器的类,斐波那契数列

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)

在20个迭代后停止

class myclass():
    def __init__(self):
        self.n = 1
        
    def __iter__(self):
        return self

    def __next__(self):
        if self.n <= 20:
            # 必须新引入1个变量a,否则循环次数是20,但输出大小都会+1
            a = self.n
            self.n += 1
            return a
        else:
            raise StopIteration()
myclass = myclass()
myiter = iter(myclass)
for item in myiter:
    print(item)

简易的列表容器迭代器,支持迭代

class listDemo():
    def __init__(self):
        self.__date = []
        self.__step = 0

    def __next__(self):
        if self.__step <= 0:
            raise StopIteration
        self.__step -= 1
        # 返回下一个元素
        return self.__date[self.__step]

    def __iter__(self):
        # 实例对象本身就是迭代器对象,因此直接返回self即可
        return self

    # 添加元素
    def __setitem__(self,key,value):
        self.__date.insert(key,value)
        self.__step += 1

mylist = listDemo()
mylist[0] = 1
mylist[1] = 2
mylist[2] = 3
mylist[3] = 4

for i in mylist:
    print(i)
posted on 2022-07-07 16:08  jiayou111  阅读(43)  评论(0编辑  收藏  举报