迭代器的介绍
什么是迭代器
迭代器是迭代取值的工具,迭代是一个重复的过程,每一次的重复都是根据上一次的结果而继续的,单独的重复并不是迭代。
# 虽说迭代是一个重复的过程,但是以下单独的重复,并不是迭代
while True:
print('hello')
# 迭代举例(也就是说,每个值每次都不一样)
l = ['x1ong','liu','li','lulu']
index = 0
while index < 4:
print(l[index])
index += 1
为什么要有迭代器
迭代器是用来迭代取值的工具,而涉及到把多个值逐个循环取出的数据类型有: 列表、元组、字符串、字典、集合、打开文件。
l = ['x1ong','liu','li','lulu']
index = 0
while index < 4:
print(l[index])
index += 1
上述迭代取值的方式只适用于有索引的数据类型:字符串、列表、元组 为了解决基于迭代器取值的局限性,Python必须提供一种取值方式,能够不依赖索引进行取值。那么就有了现在的迭代器。
如何使用迭代器
可迭代对象: 但凡内置有__iter__方法的数据类型,都是可迭代对象
s1 = 'hello'
s1.__iter__()
l = ['x1ong']
l.__iter__()
tup = (1,)
tup.__iter__()
dic = {'a':1}
dic.__iter__()
set1 = {1,2,3}
set1.__iter__()
with open('./1.txt',mode='rt',encoding='utf-8') as f:
f.__iter__()
'''
总结:
是可迭代的对象有:字符串、列表、元组、字典、集合、打开文件
'''
# 调用可迭代对象下的__iter__方法,可以将可迭代对象转换为迭代器对象
dic = {'name':'x1ong','age':17,'addr':'china'}
dic_iterator = dic.__iter__()
print(dic_iterator)
#调用迭代器下面的__next__方法, 可以将字典中的key返回。对于其他数据类型,返回的都是对应的值。
# 执行一次 返回一个k
'''
print(dic_iterator.__next__()) # name
print(dic_iterator.__next__()) # age
print(dic_iterator.__next__()) # addr
当__next()__将迭代器对象里面的值都取完的时候,再次取会抛出StopIteration错误。
# print(dic_iterator.__next__()) # 抛出 StopIteration 错误
'''
# 通过while循环取字典中的key和value
while True:
try:
print(dic_iterator.__next__()) # 取字典中的key
# print(dic[dic_iterator.__next__()]) # 取字典中的value
except StopIteration:
break
这里说下try和except的使用,它类似于if和else语句,我们可以将有可能产生报错的代码,放到try里面(类似于if里面的),而except放的则是我们程序报错之后要执行的语句(类似于else)而except StopIteration则表示,当程序要抛出StopIteration错误的时候,就执行子代码块的内容,即break终止循环。
可迭代对象和迭代器对象详解
可迭代对象又称为“可以被转换为迭代器的对象”:内置有__iter__方法
可迭代对象.__iter__() # 得到一个迭代器对象
迭代器对象:内置有__next__方法并且内置有 __iter__方法的对象
迭代器对象.__next__() # 得到迭代器的下一个值
迭代器对象.__iter__() # 得到迭代器本身,调和不调都一样
str1 = 'hello'
str_iterator = str1.__iter__() # 获得一个迭代器对象
# 迭代器对象和迭代器对象.__iter()之后的结果做is比较 结果为True,所以调和不调都一样
print(str_iterator is str_iterator.__iter__()) # True
当__next__取出的迭代器对象,被取尽时这会报错。也就是同一个迭代器对象只能被取尽一次。下次再取则直接抛出StopIteration异常。
# 文件对象本来就是一个迭代器对象,它可以直接调用__next__方法。下面我们使用while循环获取1.txt文件的所有内容
with open('./1.txt',mode='rt',encoding='utf-8') as f:
# print(f.__next__()) # 显示1.txt文件中的第一行内容
with open('./1.txt',mode='rt',encoding='utf-8') as f:
while True:
try:
print(f.__next__(),end='')
except StopIteration:
break
基于目前的知识,我们可以总结如下:
可迭代对象:字符串、元组、列表、字典、集合、文件对象
迭代器对象:文件对象
for循环的工作原理
dic = {'name':'x1ong','age':17,'addr':'china'}
# 使用while循环获取字典中的key
dic_iterator = dic.__iter__()
while True:
try:
print(dic_iterator.__next__())
except StopIteration:
break
# for循环的工作原理
'''
1、调用dic.__iter__()方法,得到一个迭代器对象
2、调用迭代器对象下的__next__()方法, 拿到一个返回值,将返回值赋值给变量key
3、循环往复步骤2,直到抛出StopIteration异常,for循环则会捕捉该异常,从而停止循环
'''
# 使用for循环获取字典中的key
for key in dic:
print(key)
迭代器的优缺点
优点
1、为序列和非序列类型提供了一种统一的迭代取值方式。
2、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
缺点
1、除非取尽,否则无法获取迭代器的长度
2、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
本文作者为blog,转载请注明。