【python】 可迭代对象、迭代器、生成器
可迭代对象 iterable
可直接作用于for循环的对象统称为可迭代对象。
有 list、 dict、tuple、set、str等数据类型,还有 generator(包括生成器和带yield的generator function)。包括了有序和无序对象。
要判断一个对象是否为iterable对象。方法如下:
from collections import Iterable
isinstance([],Iterable)
迭代器 iterator
迭代,即一些事要重复好多次,就像在循环中做的那样。
一个对象是否可迭代,全都取决于这个对象是否有__iter__方法,只要该对象实现了__iter__方法,调用对象的__iter__方法,就回返回一个迭代器,这个迭代器一定具有next方法(调用这个方法时不需要任何参数),在调用这个迭代器的next方法时,迭代器就回返回它的下一个值,当迭代器中没有值可以返回了,就回抛出一个名为StopIteration的异常,停止迭代。
准确的说,一个实现了__iter__方法的对象是可迭代的,一个实现了next方法的对象则是迭代器。
例如文件既有iter方法又有next方法,是可迭代对象也是迭代器,为什么还要iter方法呢。iter方法要使所有可迭代对象生成统一的迭代器格式。
每次调用next()方法的时候会做两件事:
1、为下一次调用next()方法修改状态
2、为当前这次调用生成返回结果
特性:不可逆,只能前进,不能后退。只能不断通过next()函数获取下一个数据,有需要的时候才生成值返回,没调用的时候就处于休眠状态等待下一次调用。
for循环就是这样工作的,for循环在循环一个对象的时候,会调用这个对象的__iter__方法,得到迭代器,然后在调用这个迭代器的next方法,去获得这个迭代器中包涵的每个值。
要判断一个对象是否为iterator对象。方法如下:
from collections import Iterator
isinstance((x for x in range(9)),Iterator)
迭代器与列表的区别
迭代器是惰性的,一个接着一个的获取值,只能往后取值。但无法获取迭代器的长度。
列表,一次性获取所有的值。如果有很多值,列表就会占用太多的内存。
例:
class test_class:
def __init__(self,start_num,stop_num):
self.start_num = start_num
self.stop_num = stop_num
def next(self):
if self.start_num < self.stop_num:
self.start_num += 1
return self.start_num
def __iter__(self):
return self
test_obj = test_class(0,3)
print test_obj.next()
>>>1
print test_obj.next()
>>>2
print test_obj.next()
>>>3
生成器
一种特殊的迭代器。(用普通函数语法定义的迭代器)
生成器的两种表达形式:
函数式生成器:使用yield关键字每次返回一个结果,一个函数中可以出现多个yield。函数之中每一个yield都会返回一个结果。每执行一个yield后,函数都会变成“挂起”(暂停)状态,下次再调用时,会从上次挂起的位置继续向下执行。
生成器表达式:使用类似于列表推导式的方法,但返回的结果不再是一个列表,而是一个生成器。
例: (i for i in range(5))
可以作用于for循环,也可以被next()函数不断调用并返回下一个值,只到最后抛出stopiteration错误表示无法继续返回下一个值。
总结:
可用于for循环的对象都是iterable类型,
可用于next()函数的对象都是iterator类型,
生成器都是iterator对象,但list、dict、str等虽然是iterable,却不是iterator。
可以使用iter()函数可以把list等iterable变成iterator。