python最重要的迭代生成器,你懂的

python 迭代器和生成器

迭代器

对于list、string、tuple、dict等这些容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数。iter()是python内置函数。 

iter()函数会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内的元素。next()也是python内置函数。在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束。

迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的_next_方法(Python3中是对象的_next_方法,Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,就要实现它的_next_方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现_iter_方法,而_iter_方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的_iter_方法返回自身self即可。

1,迭代器协议:对象需要提供next()方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代。

2,可迭代对象:实现了迭代器协议对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但可以使用内建函数iter(),把这些都变成Iterable(可迭代器对象)。

3,for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束

Python中一个实现了_iter_方法和_next_方法的类对象,就是迭代器,如下案例是计算菲波那切数列

class Fib():

    def __init__(self,max):

        #super(Fib, self).__init__()

        self.max= max

        print('first')

def __iter__(self):

        self.a= 0

        self.b= 1

        print('scond')

return self

    def __next__(self):

        fib= self.a

if fib> self.max:

            raise StopIteration

        self.a,self.b= self.b,self.a+ self.b

print('three')

return fib

# 定义一个main函数,循环遍历每一个菲波那切数

def main():

    # 20以内的数

    fib= Fib(20)

for iin fib:

        print(i)

# 测试

if __name__== '__main__':

    main()

解释说明:

在本类的实现中,定义了一个_iter_(self)方法,这个方法是在for循环遍历时被iter()调用,返回一个迭代器。因为在遍历的时候,是直接调用的python内置函数iter(),由iter()通过调用_iter_(self)获得对象的迭代器。有了迭代器,就可以逐个遍历元素了。而逐个遍历的时候,也是使用内置的next()函数通过调用对象的_next_(self)方法对迭代器对象进行遍历。所以要实现_iter_(self)和_next_(self)这两个方法。

而且因为实现了_next_(self)方法,所以在实现_iter_(self)的时候,直接返回self就可以。

总结一句话就是: 

在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的_iter_(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的_next_(self)。

注意点:_iter_(self)只会被调用一次,而_next_(self)会被调用 n 次,直到出现StopIteration异常。

生成器


延迟操作。也就是在需要的时候才产生结果,不是立即产生结果。

生成器是只能遍历一次的。

生成器是一类特殊的迭代器

第一类:生成器函数:还是使用 def 定义函数,但是,使用yield而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。

如下案例加以说明:

# 菲波那切数列

def Fib(max):

    n, a, b= 0,0,1

    while n< max:

        yield b

a, b= b, a+ b

n= n+ 1

    return '亲!没有数据了...'

# 调用方法,生成出10个数来

f=Fib(10)

# 使用一个循环捕获最后return 返回的值,保存在异常StopIteration的value中

while  True:

try:

        x=next(f)

print("f:",x)

except StopIteration as e:

        print("生成器最后的返回值是:",e.value)

break

你可能感兴趣的:(python最重要的迭代生成器,你懂的)