Iterator & Generator
**Iterator & Generator(迭代器和生成器)**:是Python中非常重要的组成部分,很多小伙伴搞不清迭代器和生成器到底是什么?如何创建迭代器和生成器?今天给小伙伴们具体讲解一下。
Iterator & Iterable
虽然今天是第一次提到Iterable(可迭代对象)和Iterator(迭代器对象),但是我们一定都使用过可迭代对象。可迭代对象可以理解为一个实例对象,具有__iter__方法。而迭代器对象可以理解为一个实例对象,既有__iter__方法,又有__next__方法。一个可迭代对象通过__iter__方法可以转换为一个迭代器对象,而迭代器对象始终是一个可迭代对象,调用__iter__方法等于其自身。简单地说,可以使用for循环遍历的都是可迭代对象,我们常见的list,tuple,set,dict,str等容器都是可迭代对象,但是不是迭代器对象。通过__iter__方法可以转换为迭代器对象。
通过collection库下面的Iterator类和Iterable可以判定对象是否为迭代器对象还是可迭代对象。
根据上面的分析可以知道,我们创建的类只要定义了__next__方法和__iter__方法,就是一个迭代器。
我们还需要掌握一个知识点,迭代器对象是一次性消费对象,因为它们没有把所有的值存在内存中,而是在运行时产生值,当我们使用迭代器对象时,迭代器对象的内容就会消失。如下例,使用了列表容器产生一个可迭代对象a=[1, 2, 3, 4, 5],并且使用__iter__方法产生了迭代器对象b,当next(b)时,会输出1,此时1就会从b中消失,同理再次使用next(b)时,2就会从b中消失,当list(b)时,所有数据都会从b中消失,但是a时不会变化的,因此我们需要另一个迭代器对象时,需要使用iter(a)再次产生一个。
生成器
Generator(生成器)也是一种迭代器,也是一次性消费对象,在写代码的时候,尤其是深度学习领域,具有大量的数据集输入,如果将数据全部保存,会受到内存的限制,而且很多数据本次用不到,这时候生成器就发挥了巨大的作用,每次使用时生成值。其实现一般有两种方式,一个是生成式,注意生成式不是列表生成式,而是将列表生成式中的中括号改成小括号,一个是使用关键字yield的函数。
在调用带有yield的函数生成器时,返回的是一个生成器对象,当函数运行到yield时,将yield的值返回,程序会暂停,并且保存当前函数的所有运行信息,当使用next方法时,程序从上次停留的地方继续执行。
生成器函数也可以接收输入值,通过send方法可以向生成器中传值。注意第一次只能通过send传入None,或者调用next方法,如果使用send不写输入参数则会报错,如果使用send传入某个非None的值也会报错。
小结
迭代器和生成器是Python中非常重要的内容,能够在特殊的情况下发挥出巨大的优势,小伙伴们务必掌握它。