python中关于迭代器,生成器,可迭代对象的描述

首先对迭代作一个简短描述:从左到右查找对象的内容可称为迭代。python中常用的迭代工具有for循环,in成员关系测试,map,sum,reduce等内置函数。

然后是介绍迭代器协议:对象要实现__next__方法,并在调用时能够返回迭代中的下一项,直至最终抛出StopIteration的异常。

再介绍可迭代对象:可迭代对象是一个庞大的概念,范围很广,主要包括三类,迭代器,序列,集合和字典。下面是可迭代对象的一个简短定义:能够实现__iter__方法的对象是可迭代对象。

自动调用__iter__方法后,返回的是一个迭代器对象。所以在使用迭代工具迭代可迭代对象时,例如for循环,都是先自动调用可迭代对象的__iter__方法,返回一个迭代器对象,接着是自动调用迭代器对象的__next__方法,返回可迭代的对象的元素。

sd = [1,3,5,6,8]
for i in sd:
    print(i)

执行结果:
在这里插入图片描述
然后是迭代器的简短定义:符合迭代器协议的对象就为迭代器。也就是能够实现__iter__和__next__方法的对象。
迭代器与可迭代对象的区别就在于__next__方法的实现。迭代器能够通过next()方法的调用不断地返回下一个值。而列表,元组,集合等可迭代对象则没有此功能。

对列表执行next()方法发生错误。
迭代器的几种生成形式:1.对列表,集合,字符串等可迭代对象使用iter()方法,就可使之成为迭代器。
在这里插入图片描述
2.通过python 内置的工具包 itertools创建迭代器。其中函数包括:count, cycle, repeat…itertools中有很多用于创建迭代器的方法。有兴趣的可以自行翻阅官方文档。

3.通过在类中使用__iter__和__next__方法来构造迭代器。下面通过一个类来实现类似range()方法的功能,当然这个类(迭代器)功能很简单。

class Myrange():
    def __init__(self,start_index,end_index):
        self.start_index = start_index
        self.end_index = end_index

    # 通过实现__iter__方法来返回一个迭代器对象
    def __iter__(self):
        return Myiteraitor(self.start_index,self.end_index)


class Myiteraitor():
    def __init__(self,start,end):
        self.start = start
        self.end = end

    # 通过实现__next__方法返回迭代器中的元素
    def __next__(self):
        if self.start < self.end:
            result = self.start
            self.start += 1
            return result
        else:
            raise StopIteration("迭代完成")


if '__name__ == __main__':
    for i in Myrange(2,5):
        print(i)

执行结果如下:
在这里插入图片描述
其实python 的许多内置类型也是迭代器。例如python的enumerate和reversed对象是迭代器;zip,filter 和map也是迭代器;文件对象也是迭代器。
由于生成器也是迭代器的一种,所以通过生成器表达式生成器函数也可生成迭代器。这个下面说。

使用迭代器要注意它的重要特性:惰性。只能使用一次,只能循环遍历一次。第二次便只会得到空值,这个在生成器下面再细说。由于再我们调用next()方法之前,迭代器不会做任何事情,因此可以创建无限长的迭代器,但不能创建无限长的列表和集合等,那样会占满你的内存。
上面的next()方法本质也是在调用迭代器对象内部的__next__方法。

下面是关于生成器的详细描述:
前面说了,生成器也是迭代器的一种,可以由生成器表达式生成器函数生成。
下图是生成器表达式的形式:
在这里插入图片描述
s就是一个生成器,表达式和列表推导式很像,只不过是把方括号换成圆括号。
下图是一个生成器函数的形式,功能很简单:
在这里插入图片描述
在函数中用yield 关键字替换return,该函数就成为一个生成器。因此就可以把yield 看成return,只是普通函数在调用后会立刻执行,而生成器在调用时不会立刻执行,只有执行next()方法或遍历它时才会真正执行。
return和yield还有一个区别是,普通函数在遇到return后会立刻结束,而生成器在执行后遇到yield会停下来(在yield把它后面的值返回后才会停下来,yield有return的功能),直到下一次再次使用next()方法,才会从上次停止的地方继续执行。
注意,for循环的本质也是不断调用next()方法,从可迭代对象中获得元素。

前面说了迭代器的重要特性:惰性,迭代器里的元素只能被使用一次,再次使用就找不到了。
下面以生成器为例:
在这里插入图片描述

如果说4在nums里,你肯定会说一定。
在这里插入图片描述
那我再问一遍呢?
在这里插入图片描述
答案是否定的,因为前面说过,in成员测试也是迭代工具,由于迭代器里的数据只能被使用一次,在使用in迭代后,里面的数据自然也就消失了。

完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值