深入理解Python迭代器与生成器

时间:2023-02-16 14:07:55

学习python的过程中,迭代器与生成器是绕不开的话题, 什么是迭代器和生成器呢?

1、迭代和它的小伙伴们。

迭代,顾名思义就是不停的重复,但是总有累了结束的时候,来个小迭代感受一下。

#不停的获得列表A中的成员,等全部获得了就结束了
A =  [1,2,3,4]
for i in A:
    print(i)

这里list A 就是可迭代的对象,就是说list具有可以迭代的功能,也可以说,list实现了python中规定的迭代协议
那么什么是python中规定的可迭代协议呢?
python 说:如果你能实现__iter__方法,并且返回一个可迭代的迭代器,我就说你是可迭代的对象。

class selfdef():
    def __iter__(self):
        return  selfiterator #这里selfiterator是一个可迭代的迭代器
   ......

那么什么是python中规定的迭代器呢?因为selfiterator实现了__next__方法,就称它为迭代器,所以迭代器协议就是对象实现了__next__方法。满足迭代器协议的称之为迭代器

class selfiterator():
    def __init__(self):
        self.name = 'this is a iterator'
        self.num = 0
    def __next__(self):
        i = self.num
        if i > 10:
            self.num -= 1
            return  i
        else:
            raise StopIteration

for item in obj 这是python的语法糖,如果obj 是一个可迭代对象,它自动实现了先调用iter函数将其转为迭代器,然后对迭代器不断调用next方法,并将获取的值赋予item,并自动处理异常。

让我们分析一下list 来加深印象

list 可以像下面这样来用,说明它是可迭代的对象,满足可迭代协议,即内部实现了__iter__方法,返回了一个可迭代的迭代器

list =[1,2,3,4]
for item in list
    print (item)

class List:
    def __iter__(self):
        return iter(self) #调用了self.__iter()__函数返回底层的迭代器对象,该对象实现了__next__方法

list 是可迭代的对象,但它并不是可迭代的迭代器,因为它本身并没有实现next方法,并不能通过next(list)来调用。

迭代器总结

1.对象-》实现iter方法变为可迭代对象-》实现next方法变为可迭代的迭代器
2.for…in…语法糖,自动实现了调用 iter 与 next

2、生成器-特殊的迭代器

python 中提供了2中迭代器生成方法
(1)列表表达式转化

a = [x for x in range(5)] #[0,1,2,3,4]
b= (x for x in range(5)) #generator object

(2)生成器函数

#普通函数使用yield 代替return 函数变为生成器函数
#当调用这个“函数”的时候,它会立即返回一个迭代器,而不立即执行函数内容,直到调用其返回迭代器的next方法是才开始执行,直到遇到yield语句暂停。 
#生成器自动实现了迭代器协议 ,因此可以调用它的next方法
def count(n):
    while n > 0:
        yield n
        n -=1
cal = count(10) #返回一个迭代器
next(cal) #10
next(cal) #9
#或者仍使用语法糖
for i in count(10)
    print(i)

生成器的作用

(1)生成器主要是为简化使用迭代器而生,生成器函数简化了迭代器的实现,不用去实现复杂的iter与next函数,只需要一个yield:
(2)生成器实现了延迟执行,在进行大数据计算是节约大量内存,对比一下两个计算方法

a = sum([x for x in range(10000)]) #需要分盘生成存储10000个数的列表的内存
b = sum(x for x in range(10000)) #使用迭代器协议访问生成器对象,不需要预先全部生成列表

(3)python 通过生成器实现了协程,即实现了单线程内,不同任务函数之间的协同工作。关于协程的使用我预计在下一部分结合进程线程进行学习总结。

看到这里,小伙伴们有没有清楚一点呢?欢迎大家给我评论,一起交流,gong’t进步!