首先,我们从简单的容器开始。
容器:是一种把多个元素组织在一起的数据结构,其中的元素可以迭代获取,可以用in,not in,来判断是否存在容器中,这类数据结构的所有元素是存储在内存中的,像迭代器,生成器的数据元素只有一部分存在内存中。
python中常见的容器:
list/deque
set/fronzensets
dict/defaultdict/Ordereddict/Counter
tuple/namedtuple
str
1、容器中的每个元素都是可以获取到的,这是由于容器是可迭代对象的原因,而不仅仅是因为它存在每个元素。但是,并不是所有的容器都是可迭代的。比如说bloomfilter,虽然bloomfilter可以检测某个元素是否在其中,但是并不能获取每个存入其中的值,因为bloomfilter其实并没有存储每个元素,只是对每个元素是否存在做了标记,是将每个元素的hash值映射到了数组中;
2、并不是只有容器是可迭代的,很多其他的对象都是可迭代对象----凡是可以返回一个迭代器的对象都是可迭代对象(这句话有点绕);
例子:
x=[1,2,3]
x是一个可迭代对象,可以简单的把一个可迭代对象理解为容器(如list,set,dict等,但是要注意可迭代对象并不是只有容器)
y= iter(x),z=iter(x)
此时y,z是2个独立的迭代器,迭代器内部有一个状态,这个状态的作用就是标记当前迭代到哪个元素了,以便于下次迭代的时候能够正确的迭代到正确的元素;每个迭代器都有一个确定的迭代类型,如x是list_iterator,如果x是set,那么x就是set_iterator,
因为可迭代对象x(list)内部定义了一个__iter__方法,该方法就是返回一个迭代器;
那么,什么是一个迭代器呢?
迭代器是一个带状态的对象。该对象的能力是在你调用next()函数的时候,如next(y)返回容器中的下一个值,任何一个实现了__iter__()、__next__()方法的对象都是迭代器。如果容器中没有更多的元素了,那么就抛出一个StopIterator异常,迭代器就是实现了工厂模式的对象.(这里需要脑补一下工厂模式)
为什么实现了 __iter__、__next__方法的对象就是迭代器呢?
1、迭代器首先是一个可迭代对象,而可迭代对象必须实现__iter__方法;
2、迭代器同时要能够返回可迭代对象的下一个值,所以当调用next()函数的时候,需要能够返回值,所以必须定义__next__方法;
那么调用next()方法做了什么事情呢?
1、为下一次调用next()函数做好准备,即修改状态
2、返回当前的可迭代对象的值