对于python中迭代器和rang()对象的理解

对于python中迭代器和rang()对象的理解

  • 对于python中迭代器和rang()对象的理解
    • 可迭代对象
    • 迭代器
    • 探究
    • 猜想、分析和结论


对于python中迭代器和rang()对象的理解

在课堂上学python的时候,很多东西其实并不是很了解,比如迭代器这个东西,只是止于它怎么用,其实不知道它的本质到底是什么,只觉得它是可以不断“一代一代”输出的东西,所以以前以为range这些只要可以用for一代一代拿出来的都可以算,但是随着自学的深入,我又有了新的理解

下面实验探究基于:python3.7.3的jupyter notebook

刚刚接触了generator,知道了他也是可迭代的,就引起了对迭代器的兴趣
  那么什么是迭代器呢,查阅了别人的blog和百科之后,我记录如下
  迭代是访问一个元素集合的一种方式,从第一个元素知道访问完所有元素,只会向前不会后退。

可迭代对象

可以直接作用于for循环的对象,称为iterable

  • 一类是数据的各种集合,list,dict,set,str,tuple···
  • 还有一类就是generator(生成器)

迭代器

迭代器(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
  1. 这里我们发现迭代器的大小(或者说他说储存的内容)和他能被迭代多少次,能出多少元素无关,而且我们还发现原对象没有规律或者被改变了,也不影响迭代器。这是为什么呢?
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]:
  1. 但是,range()产生的对象可以迭代取出,但是他不能用next函数,所以他不是迭代器,他和迭代器还有另一个大分别如下
[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. 他们之间的区别在哪里呢?我们发现所谓迭代器的迭代,是不可逆的,我们实际上已经失去了回复的可能,但是range对象则不是,它可以重复迭代毫无影响。这又是为什么呢?
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
  1. 这里我们又发现,和迭代器类似的,range对象的大小不受到元素个数的影响,这又是为什么呢,range对象到底是怎么储存的呢?

猜想、分析和结论

我自己的理解是:
我们都知道python中一切都是对象,当你给一个变量重新赋值的时候,原来的数据其实并没有消失,只是失去了指向他的指针。那么,当一个变量是元素集合的时候,所谓x,说的是从开头到’\n’的所有
但是迭代器可能是只需要两部分(猜的,加入了自己的理解):头指针,尾指针。所谓的迭代器对象,只是两个指针而已
但是range对象则不同,我想,range对象由一种规律和当前位置指针组成,就像数学中的符号f一样,range是一个序列(你可以通过索引取值),但是他不像list这些储存元素,他记载了规律,然后现场计算出元素。
就像是数学分析中f这个符号,它不记载所有的函数值,只有当你给出自变量之后他才会计算出来函数值。所以所谓的range对象,只是规律+指针而已,他没有数据,所以它的大小不受他能迭代出多少元素的限制

可能是因为迭代器像是一个由两个指针构成的指示装置,当迭代器产生的时候,原对象就被复制一遍(只有这样,当原对象改变的时候迭代器才能不变),迭代器不对数据负责,他只是两个指针,所以迭代器的大小和数据的多少无关。
所以迭代器和普通的可迭代对象不一样,可迭代对象的变量管着整个的对象(数据),但是迭代器却和元素分离了,元素是死是活不管,他只指向它,所以迭代器不可逆,他不管元素什么样,指针只是往前走,他也不知道规律是什么,所以也不可能返回原来的状态了。

你可能感兴趣的:(#,对于概念的研究思考)