欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

深入理解python迭代、可迭代对象、迭代器及生成器

程序员文章站 2023-03-31 09:09:44
迭代 通常意义上的迭代是指:重复执行一系列运算,从前面的量依次推出后面的量的过程,每一次迭代的结果,会作为下一次迭代的初始值。 在c、c++、java等编程语言中的for循环语句,就是一个迭代过程,例如: 这种for循环语句比较符合迭代的含义,for语句中给定了一个初始输入 i=0 ,然后开始执行一 ......

迭代

通常意义上的迭代是指:重复执行一系列运算,从前面的量依次推出后面的量的过程,每一次迭代的结果,会作为下一次迭代的初始值。

在c、c++、java等编程语言中的for循环语句,就是一个迭代过程,例如:

for(int i=0;i<100;i++)
{
   cout << i << endl;
}

这种for循环语句比较符合迭代的含义,for语句中给定了一个初始输入 i=0 ,然后开始执行一个重复推导变量 i 是否小于 100 ,如果小于就对 i 加1并执行循环体中代码的过程,且每次执行后的结果将作为下一次推导的输入值,这个过程就是迭代。

python中,也使用了 for 关键字来实现类似过程,具体形式为 for ... in ... ,当然迭代过程也可以通过while循环语句等来实现,但不在本文讨论范畴,这里不做说明。在python中通常使用 for ... in ... 的形式来遍历一个list或tuple等对象,这种遍历过程,通常称为迭代(iteration)。例如:

深入理解python迭代、可迭代对象、迭代器及生成器

上图中,通过for语句来遍历列表l,实现语句块的重复执行过程。这里之所以每次迭代时都让num的值加3,是为了说明语句块中对num进行修改后的值并不会带入到下一次迭代过程,这里应注意与c、c++、java等语言的for循环语句的区别。至于为什么是这样,可以查阅python语法中for语句的执行原理,这里不再详述。

可迭代对象与迭代器

可迭代对象:使用内置iter函数可以获取迭代器的对象,称为可迭代对象。通常指实现了能返回迭代器的__iter__方法或实现了__getitem__方法且其参数从0开始索引的对象。

迭代器:指实现了无参数的__next__方法的对象。__next__方法返回序列中的下一个元素;如果没有元素了,则抛出stopiteration异常。通常情况下,迭代器也应该实现__iter__方法,迭代器的__iter__方法应该返回其自身(self),因为实现了__iter__方法,所以迭代器可迭代。

区别与联系:迭代器可以迭代,但可迭代对象不是迭代器。可迭代对象一定不能是自身的迭代器,即可迭代对象一定不能实现__next__方法;迭代器应该一直可以迭代,其__iter__方法应该返回自身。示例:

class iteratorobj:

    def __init__(self, max):
        self.a = 0
        self.b = 1
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.max:
            raise stopiteration()
        return self.a

class iterableobj:

    def __init__(self, max):
        self.max = max

    def __iter__(self):
        return iteratorobj(self.max)

python中for循环遍历的本质就是调用遍历对象的__iter__方法,得到一个迭代器,再调用迭代器的__next__方法依次获取兑现的值并自动捕获stopiteration异常。

生成器

生成器是一种特殊的迭代器,可通过使用迭代器的方法使用生成器。

python定义生成器的方法有两种:

生成器函数:使用普通函数的定义语法定义,但函数体内必须包含yield关键字,即包含yield语句的函数都被称为生成器。生成器函数虽然看上去像函数,但与函数的行为截然不同。区别在于生成器函数不是使用return语句返回一个值,而是可以生成多个值,每次生成一个。每次使用yield生成一个值后,函数被中断,在此处停止执行,再次被调用时,函数将从上一次停止的地方开始继续执行。例如:

深入理解python迭代、可迭代对象、迭代器及生成器

注意:当生成器因没有可生产的值退出时,同样会抛出stopiteration异常。

生成器表达式:类似于列表推导,只不过要将列表推导中的[]换成()。例如:

深入理解python迭代、可迭代对象、迭代器及生成器

上图中,当第6次调用next(g)时,因没有值可生产而抛出了stopiteration异常。

以上。