【一】迭代器介绍
- 迭代器就是迭代取值的工具,而迭代是重复反馈过程的活动
- 其目的通常是为了逼近所需的目标或结果,而每一次迭代得到的结果会作为下一次迭代的初始值
#只会重复让你输入信息,并不是迭代过程
while True:
msg = input("请输入信息:").strip()
print(msg)
#下面是一个迭代过程,将列表中的值一个一个的取出来了
num_list = [1,2,3,4,5]
count = 0
while count < len(num_list):
print(num_list[count])
count += 1
# 1
# 2
# 3
# 4
# 5
【二】可迭代对象
【1】什么是可迭代对象
- 通过索引的方式进行迭代取值,但仅适用于序列类型:字符串,列表,元组
- 对于没有索引的字典、集合等非序列类型,必须找到一种不依赖索引来进行迭代取值的方式,这就用到了迭代器。
【2】可迭代对象
- 从语法形式上讲,内置有__iter__方法的对象都是可迭代对象
# 【1】整数类型 --- 不是
num = 1
print(num.__iter__)
# AttributeError: 'int' object has no attribute '__iter__'. Did you mean: '__str__'?
# 【2】浮点类型 --- 不是
num_float = 1.2
print(float.__iter__())
# AttributeError: type object 'float' has no attribute '__iter__'. Did you mean: '__str__'?
# 【3】布尔类型 ---不是
is_bool = True
print(bool.__iter__)
# AttributeError: type object 'bool' has no attribute '__iter__'. Did you mean: '__str__'?
# 【4】字符串类型
name = 'ligo'
print(name.__iter__)
# <method-wrapper '__iter__' of str object at 0x000001A3EBA40A30>
print(name.__iter__())
# <str_iterator object at 0x000001A3EBC27FD0>
# 【5】列表类型
num_list = [1, 2, 3, 4, 5]
print(num_list.__iter__)
# <method-wrapper '__iter__' of list object at 0x000001A3EBA4F900>
print(num_list.__iter__())
# <list_iterator object at 0x000001A3EBC27FA0>
# 【6】字典类型
user_dict = {"name": "ligo"}
print(user_dict.__iter__)
# <method-wrapper '__iter__' of dict object at 0x000001A3EBA40980>
print(user_dict.__iter__())
# <dict_keyiterator object at 0x000001A3EBA90400>
# 【7】元祖类型
num_tuple = (1, 2, 3, 4, 5)
print(num_tuple.__iter__)
# <method-wrapper '__iter__' of tuple object at 0x000001A3EBA91440>
print(num_tuple.__iter__())
# <tuple_iterator object at 0x000001A3EBC27FA0>
# 【8】集合类型
num_set = {1, 2, 3, 4, 5}
print(num_set.__iter__)
# <method-wrapper '__iter__' of set object at 0x000001A3EBA72A40>
print(num_set.__iter__())
# <set_iterator object at 0x000001A3EBA78580>
【3】小结
- 非可迭代对象:整数类型、浮点类型、布尔类型
- 可迭代对象:字符串类型、列表类型、字典类型、元祖类型、集合类型
【三】迭代器对象
【1】什么是迭代器对象
- 调用obj.iter()方法返回的结果就是一个迭代器对象
- 迭代器对象是内置有iter和next方法的对象,打开的文件本身就是一个迭代器对象
- 执行 迭代器对象.iter() 方法得到的仍然是迭代器本身
- 而执行 迭代器.next() 方法就会计算出迭代器中的下一个值
【2】迭代器对象
# 【1】字符串类型
name = 'ligo'
name_iter = name.__iter__()
print(name_iter)
# <str_iterator object at 0x000001EBF65149D0>
print(name_iter.__next__()) # l
print(next(name_iter)) # i
print(name_iter.__next__()) # g
print(next(name_iter)) # o
# 【2】列表类型
num_list = [1, 2, 3, 4, 5]
num_list_iter = iter(num_list)
print(num_list_iter)
# <list_iterator object at 0x00000147E89A9E10>
print(num_list_iter.__next__()) # 1
print(next(num_list_iter)) # 2
# 【3】字典类型
user_dict = {"name": "ligo", "password": 123}
user_dict_iter = iter(user_dict)
print(user_dict_iter)
# <dict_keyiterator object at 0x00000202394C0400>
print(user_dict_iter.__next__()) # name
print(next(user_dict_iter)) # password
# 【4】元祖类型
num_tuple = (1, 2, 3, 4, 5)
num_tuple_iter = iter(num_tuple)
print(num_tuple_iter)
# <tuple_iterator object at 0x0000022FE45D78E0>
print(num_tuple_iter.__next__()) # 1
print(next(num_tuple_iter)) # 2
# 【5】集合类型
num_set = {1, 2, 3, 4, 5}
num_set_iter = iter(num_set)
print(num_set_iter)
# <set_iterator object at 0x0000024B21D40A40>
print(num_set_iter.__next__()) # 1
print(next(num_set_iter)) # 2
【3】获取迭代器对象的两种方式
#【1】__iter__()
name = 'ligo'
name_iter = name.__iter__()
print(name_iter)
# <str_iterator object at 0x00000204E6859E10>
#【2】iter()
name = 'ligo'
name_iter = iter(name)
print(name_iter)
# <str_iterator object at 0x00000206870E78E0>
【4】迭代器对象取值的两种方式
#【1】__next__()
name = 'ligo'
name_iter = name.__iter__()
print(name_iter)
# <str_iterator object at 0x00000204E6859E10>
print(name_iter.__next__()) # l
#【2】next()
name = 'ligo'
name_iter = name.__iter__()
print(name_iter)
# <str_iterator object at 0x00000204E6859E10>
print(name_iter.__next__()) # l
print(next(name_iter)) # i
【5】小结
- 具有 iter() 和 next() 的对象就是迭代器对象
- 八大基本数据类型中除了整数类型、浮点数类型、布尔类型,其他都是迭代器对象
- 可迭代对象是具有 iter() 的对象,迭代器对象是具有 iter() 和 next() 的对象,所以迭代器对象一定是可迭代对象
【四】迭代器的优缺点
【1】优点
- 不再需要索引取值,并且取到这个值的时候就会保存到当前的状态,下一次从这个位置开始向下取值
- 惰性计算:
- 迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值
- 就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型
- 如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的
【2】缺点
- 除非取尽,否则无法获取迭代器的长度
- 只能取下一个值,不能回到开始,迭代器可以重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next
- 若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值