python.迭代器超级解读

iter()

说明:

1,迭代器与可迭代对象

迭代通俗叫法就是循环,循环有好几种,单次正循环,单次逆循环,无序循环,无序多次逆循环........全部列出来,得有十几种,而迭代就是单次有序正循环,被循环的那个物体集就叫可迭代对象,可迭代对象是一个复数,里面至少有一个或多个东西供迭代(循环),比如字串'hello world',再比如,字典列表等等,也就是说,只要是一个序列集合体都叫可迭代对象,但可迭代对象并不能直接拿来迭代,把序列集合体变成能够迭代的函数就叫迭代器(循环器),有很多内置函数能够直接创造这种集合体,比如map()函数,iter()函数或enumerate函数等。

迭代器创造的集合体是一段内存地址(不知道算不算一种数据格式??),并不能直接呈现,可以通过next()或for循环返回,也可以用list()或str()来转换成可见集合体。

2,迭代器的精华就是按照需求,一次只返回一个结果,而不是一口气一次性的返回一个对象列表,因此不用考虑内存暴增造成的性能下降,它比for循环的优点要多,特别是对大文件读取多或程序有过多交叉引用时,迭代器更显所长!由于不能一下看清所有的值,在用迭代器之前应该对结果有明确可预见性,所以我们可以把迭代器包裹在一个list()函数中,从而才能一次性看到它们所有的值。

3,可迭代对象支持内置函数iter和enumerate,通过对可迭代对象调用iter函数或enumerate函数,会返回一个迭代器,而“迭代器”支持内置函数next,通过不断对其调用next方法,会依次返回序列中的每一个对象,最后到达序列末尾时,会引发StopIteration异常。

说明一点,对迭代器调用iter方法,则会返回迭代器自身。

注意,这个next()也是一个内置函数,不是某个对象方法,所以调用时,对象应传给next()而不应把它当成对象方法来调用。

例子:

a ='asdfghjkl'   #可迭代对象

b=iter(a)        #迭代器函数把可迭代对象转成可迭代序列集。

next(b)      →'a'    #一直调用,一直按序返回,直到结束。

print(a is b)   →False  #a可迭代对象,b是迭代器。

print(b is iter(b))     →True     #迭代器调用iter返回迭代器自身

4,迭代原理:(for循环原理)

当任何可迭代对象传入到for循环或其他迭代工具中进行遍历时,迭代工具都是先通过iter函数获得与可迭代对象对应的迭代器,然后再对迭代器调用next函数,不断的依次获取元素,并在捕捉到StopIteration异常时确定完成迭代,这就是完整的迭代过程。这也称之为“迭代协议”。

5,迭代文件:

外部文件读入python中,可以一次打开全部,也可一行一行读取。open函数返回的已打开的文件对象,再调用next()函数也是可以一行一行的读取,直至文件结束,那很显然,他也是可迭代对象。

a=open('文本文件.txt')

print(next(a))   →#一行文本

print(next(a))    →#二行文本

print(next(a))    →#三行文本

print(next(a))    →#四行文本

...........

也可以用for循环

a=open('文本文件.txt')

for i in a.readlines():

    print(i ,end=' ')

→  一行文本

二行文本

三行文本

........

虽然readlines方法在功能上可用,但从内存上来看,非常糟糕,他是一次性把整个文件加载到内存,如果文件太大,以至于计算机内存不够,甚至不能够工作。而我们的迭代器则不然,迭代器是按需,一次只读取一行,因此对内存爆炸问题有了很好的免疫。

6,迭代字典:

文件和列表对象都是实际的序列,字典也是一种可迭代对象,但是他的迭代器却比较特殊,在迭代环境中,会每次自动地返回一个键名(key),也可以把它设置成值(value)或两者都有(items),但它的返回是无序的。

例子:

a={'a':5,'b':2,'c':3}
for i in a:        #默认迭代字典键名
    print(i)       →键名
for i,v in a.items():     #键值成对出现
    print(i ,':',v)            →键一值
for i in a.values():     #迭代字典的值
    print(i)                 →值
b=iter(a)       #默认迭代键名
print(next(b))
c=iter(a.values())    #设置迭代字典值
print(next(c))
d=iter(a.items())   #返回元组形式的键值对
print(next(d))

7,range()函数迭代:

range()函数的返回值也是一个可迭代对象,可以用iter()函数把它转成一个迭代器。

a=range(8)

b=iter(a)

print(next(b))    →0  #从0开始到7共8个数。

8,enumerate函数迭代器:

enumerate函数传入一个可迭代对象,就返回一个带索引号的迭代器,他的迭代器就是他自身,常与for搭配使用,当调用next()函数时返回一个元组,它与iter()函数功能一样,接收两个参数,第二个参数指定序号的起始号,为可选参数,默认为0。

例子:

b=['a','b','c']

for i in enumerate(b):

    print(i)

→(0,a)(1,b)(2,c)

c={'a':1,'b':2,'c':3}

for i in enumerate(c.items()):

    print(i)

→(0,('a',1))(1,('b',2))(3,('c',3))

 

a=enumerate('fghjjkkkl')   #默认使用

print(next(a))     →(0 'f')

b=enumerate('asdfgh',4)   #带起始序号参数

print(b)     →(4 'a')

9,迭代器的精华就是按照需求,一次只返回一个结果,而不是一口气一次性的返回一个对象列表,因此不用考虑内存暴增造成的性能下降,它比for循环的优点要多,特别是对大文件读取多或程序有过多交叉引用时,迭代器更显所长!由于不能一下看清所有的值,在用迭代器之前应该对结果有明确可预见性,所以我们可以把可迭代器包裹在一个list()函数中,从而才能一次性看到它们所有的值。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值