Python 迭代器与生成器

参考资料: 

几分钟听懂迭代器 【哔哩哔哩教程】 (迭代器讲的很好)

Python迭代器与生成器介绍及在Pytorch源码中应用

Python 迭代器深入讲解 |【AsyncIO从入门到放弃#1】 (生成器讲得很好)

Python进阶 | 五分钟带你弄懂迭代器与生成器

 

迭代器

在python中,如果一个对象有__iter__和__next__方法,那么这个对象就是一个迭代器。

我们也可以调用__iter__函数把可迭代对象变为迭代器。

可迭代对象只有__iter__方法,没有__next__方法。

迭代器既有__iter__方法,也有__next__方法。(这也是迭代器协议所规定的)

在python中,这种前后都有双下划线的方法,既可以用 对象.__iter__() 来调用,也可以直接 iter(对象) 来调用。

 

对于一个for循环中的迭代,中间过程发生了两件事:

  1. __iter__函数把可迭代对象变为迭代器;
  2. 调用迭代器的__next__函数,返回一个元素。

 

我们自己创建一个简单的迭代器:

class Iterator_test():
    def __init__(self, data):
        self.data = data
        self.length = len(data)
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index < self.length:
            self.index += 1
            return self.data[self.index-1]
        else:
            raise StopIteration

case = Iterator_test([1, 2, 3])

# ========= 用循环的方式获取每一次迭代返回的值 ===========
# for num in case:
#     print(num)   # 输出:1 2 3


# ========= 调用iter方法获取每一次迭代返回的值 ===========
print(next(case))       # 输出:1
print(next(case))       # 输出:2
print(case.__next__())  # 输出:3
print(next(case))       # 输出:报错,StopIteration的错误

 

生成器

通常,我们把含有yield的函数称之为生成器函数generator function,把调用生成器函数返回的结果称为生成器generator (或者称为生成器对象)。

生成器是迭代器,不同的是生成器的实现更简洁。

 

__next__函数是由yield控制的。

return的作用是触发StopIteration异常。

生成器示例:

def count(start=0, step=1, end=8):
    n = start 
    while n < end:
        yield n      
        n += step

if __name__ == '__main__':
    c = count(end=5)   # c是生成器

    # # ===== 用next函数来返回值
    # print(next(c))   # 输出 0
    # print(next(c))   # 输出 1

    # ===== 用for循环来返回值,for循环实际上也是会调用next函数
    for i in c:
        print(i, end=' ')   # 输出:0 1 2 3 4 

 

 

总结一下yield的作用:

  1. 把函数变为生成器函数;
  2. 当程序运行到yield语句这里时,yield语句右边的对象作为next()的返回值;
  3. 返回一个值之后,程序会在yield语句这里暂停,当再次使用next()函数时,程序从该位置继续运行。

class实现的迭代器和yield实现的迭代器比较:

 

posted @ 2020-05-07 18:44  Picassooo  阅读(490)  评论(0编辑  收藏  举报