在课堂上学python的时候,很多东西其实并不是很了解,比如迭代器这个东西,只是止于它怎么用,其实不知道它的本质到底是什么,只觉得它是可以不断“一代一代”输出的东西,所以以前以为range这些只要可以用for一代一代拿出来的都可以算,但是随着自学的深入,我又有了新的理解
下面实验探究基于:python3.7.3的jupyter notebook
刚刚接触了generator,知道了他也是可迭代的,就引起了对迭代器的兴趣
那么什么是迭代器呢,查阅了别人的blog和百科之后,我记录如下
迭代是访问一个元素集合的一种方式,从第一个元素知道访问完所有元素,只会向前不会后退。
可以直接作用于for循环的对象,称为iterable
迭代器(iterator),尤指可以被next()函数调用返回下一个值的对象,list,str,dict,tuple,set这些数据集合不能被调用,不是迭代器,但是所有可迭代对象都可以用iter函数转换成迭代器,迭代器也是可迭代对象。
理论是空洞无趣的,下面通过实验探究一下他们到底是什么
下面的sys.getsizeof()函数是用于获取对象的大小的
1 x
2 [1, 2, 3, 4, 5]
3
4 x
5 next(x)
6 ---------------------------------------------------------------------------
7 TypeError Traceback (most recent call last)
8 <ipython-input-37-92de4e9f6b1e> in <module>
9 ----> 1 next(x)
10
11 TypeError: 'list' object is not an iterator
12
13
14 x
15 a = iter(x)
16
17 next(a)
18 1
x = [1,2,3,4,5,6,7,8,9,10]
In [46]:
a = iter(x)
In [47]:
sys.getsizeof(a)
Out[47]:
56
x = [1,2,3,4,5,10]
In [74]:
a = iter(x)
In [75]:
sys.getsizeof(a)
Out[75]:
56
In [76]:
x = 1
next(a)
Out[76]:
1
In [77]:
next(a)
Out[77]:
[x*3 for x in a]
Out[48]:
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
In [49]:
[x*3 for x in a]
Out[49]:
[]
b = range(10)
[x*3 for x in b]
Out[50]:
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
In [51]:
[x*3 for x in b]
Out[51]:
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
1 x = range(5)
2 In [12]:
3 import sys
4 print(sys.getsizeof(x))
5 x = [1,2,3,4,5]
6 print(sys.getsizeof(x))
7 >>>48
8 >>>104
9
10 In [13]:
11 print(sys.getsizeof(1))
12 >>>28
13
14 In [14]:
15 print(sys.getsizeof(2))
16 28
17 x= range(100)
18 In [16]:
19 print(sys.getsizeof(x))
20 48
我自己的理解是:
我们都知道python中一切都是对象,当你给一个变量重新赋值的时候,原来的数据其实并没有消失,只是失去了指向他的指针。那么,当一个变量是元素集合的时候,所谓x,说的是从开头到’\n’的所有
但是迭代器可能是只需要两部分(猜的,加入了自己的理解):头指针,尾指针。所谓的迭代器对象,只是两个指针而已
但是range对象则不同,我想,range对象由一种规律和当前位置指针组成,就像数学中的符号f一样,range是一个序列(你可以通过索引取值),但是他不像list这些储存元素,他记载了规律,然后现场计算出元素。
就像是数学分析中f这个符号,它不记载所有的函数值,只有当你给出自变量之后他才会计算出来函数值。所以所谓的range对象,只是规律+指针而已,他没有数据,所以它的大小不受他能迭代出多少元素的限制
可能是因为迭代器像是一个由两个指针构成的指示装置,当迭代器产生的时候,原对象就被复制一遍(只有这样,当原对象改变的时候迭代器才能不变),迭代器不对数据负责,他只是两个指针,所以迭代器的大小和数据的多少无关。
所以迭代器和普通的可迭代对象不一样,可迭代对象的变量管着整个的对象(数据),但是迭代器却和元素分离了,元素是死是活不管,他只指向它,所以迭代器不可逆,他不管元素什么样,指针只是往前走,他也不知道规律是什么,所以也不可能返回原来的状态了。