python迭代器与生成器
Iterator(迭代器)可以让我们完成对其的循环遍历。与普通list相比它一次只返回一个数据,占用更少的内存,下一次执行又从上次的结果继续往后执行,可以通过next()方法逐个获取值,list则列出所有项,它通过index获取值。
先介绍生成迭代器个一个内置方法iter,它可以将一个list或者字符串等转换为一个Iterator,如下:
iter将a,b转换为了迭代器,通过next来获取其元素,每次仅获取一个,注意,迭代器在溢出后会报StopIteration的错误,我们可以将其捕获,或者用for循环,for循环是对这个错误做了处理的,但有时候你会需要观察中间过程。
迭代器更大的功劳是提供了一个统一的访问集合的接口,只要定义了__iter__()方法对象,就可以使用迭代器访问,这意味着,我们可以迭代我们自己定义的对象,下面写一个简单的实现说明。
上面我们通过next来逐个访问元素,那么我们也可以在实现了__iter__的类中自己定义next来完成迭代,所以上面的代码还可以这么写。
一般都会把生成器与迭代器放在一起说,因为我们可以使用生成器来生成一个可迭代的对象,这就需要神奇的yield了,yield会将值返回,但在下次执行时(next)会继续按照上次停止的地方继续往下执行,如果需要的话我们可以使用list(iterator)将其转化为list或者tuple等类型。
我们可以用生成器将上面的遍历类对象的实现再次改造一下,
你可以在生成器中定义自己想要的实现,只要将其在__iter__中返回就可以完成对其的迭代,这样我们就可以有针对性的进行设计了。
生成器还有专有的生成器表达式,格式和List comprehensions类似,比如这样一个表达式:
只要我们将列表解析表达式的[]换为()就可以了,解释器会自动识别为生成器表达式,例如:
b返回的是一个生成器,可以调用next来执行他。
生成器还有两个重要的方法就是send()和close(),send可以执行生成器,并为yield赋值,若是赋空值则认为和next一样,但是需要注意,在没有执行到yield的时候不可以执行send(args),因为没有地方让他赋值,而close是用来关闭生成器的,生成器被关闭不运行执行next或send,例子如下: