迭代器
一、可迭代对象
1.1 概念
什么是迭代?
迭代就是每一次的结果必须依赖于上一次的结果
就是更新换代,v1.0 v2.0 v3.0
什么是可迭代?
可迭代在python中可以理解为是否支持for循环
可迭代对象是?
通过索引的方式进行迭代取值,实现简单,但仅适用于序列类型:字符串,列表,元组。对于没有索引的字典、集合等非序列类型,必须找到一种不依赖索引来进行迭代取值的方式,这就用到了迭代器。
要想了解迭代器为何物,必须事先搞清楚一个很重要的概念:可迭代对象(Iterable)。从语法形式上讲,内置有__iter__方法的对象都是可迭代对象。
内置的意思是python自带的,解释器中已经存在的,我们可以直接使用的
我们学习的数据类型中,
不是可迭代对象: int, float, 函数对象
是可迭代对象: 字符串、列表、元组、字典、集合、文件对象
# a = 1 # 没有
# b =1.1 # 没有
c = 'hello' # 有
d = [11, 22, 33, 44]
e = {'username': 'ly'}
f = {11, 22, 33}
g = (11, 22, 33)
# s = True # 没有
x = open('a.txt', 'w')
1.2 使用
c.__iter__()
d.__iter__()
e.__iter__()
f.__iter__()
g.__iter__()
x.__iter__()
查看数据类型可以使用的方法:
1.句点符
2.函数名()
print(c)
print(c.__iter__()) # <str_iterator object at 0x0000017E0C21C610>
print(iter(c)) # <str_iterator object at 0x000001B18D4DC610>
# print(c.__len__()) # 5
# print(len(c)) # 5
'''一般双下滑先开头的方法都有一个简便的写法,就是函数名()'''
二、迭代器对象
2.1 概念
1.什么是迭代器对象?
是由可迭代对象调用__iter__方法产生的
2.迭代器对象判断的本质是看:是否有__iter__方法和__next__方法
'''文件对象即是可迭代对象又是迭代器对象'''
3.如何生成迭代器
可迭代器对象调用__iter__方法得到迭代器对象
迭代器一定是可迭代对象,
可迭代对象不一定是迭代器
4.如何迭代取值
可迭代对象调用__next__方法
5.迭代器对象的作用:
迭代给我们提供了一种不依赖索引取值的方法
正因为有迭代器的存在 我们的字典 集合才能够被for循环
2.2 使用
2.2.1 可迭代对象与迭代器对象
# 迭代器使用:以字符串为例
c = 'hello' # c是可迭代对象
res = c.__iter__() # res是迭代器对象
'''可迭代对象调用__iter__会成为迭代器对象 迭代器对象如果还调用__iter__不会有任何变化 还是迭代器对象本身'''
s = 'hello'
res1 = s.__iter__()
print(res1.__next__) # h
res2 = s.__iter__().__iter__()
print(res2.__next__) # h
res3 = s.__iter__().__iter__().__iter__()
print(res3.__next__) # h
2.2.2 取值
# 1.索引:
c[0] # h
# 2.迭代器:
print(res.__next__()) # 迭代取值 for循环的本质(每调一次取一次值)
# 输出结果:h
其他数据类型:
d.__iter__().__next__()
e.__iter__().__next__()
f.__iter__().__next__()
g.__iter__().__next__()
文件类型比较特殊
# 文件类型比较特殊
x.__iter__().__next__()
# 文件可以直接使用__next__
x.__next__()
'''文件既是可迭代对象,又是迭代器''
取不到值
e = {'username': 'ly', 'age': 18}
res = e.__iter__()
print(res.__next__()) # username
print(res.__next__()) # age
# 取不到值,会直接报错!
print(res.__next__()) # StopIteration
print(next(res)) # username
print(next(res)) # age
print(next(res)) # StopIteration
2.2.3 练习题
# 练习题:hello
res = c.__iter__()
print(res.__next__()) # h
print(res.__next__()) # e
print(res.__next__()) # l
print(res.__next__()) # l
print(res.__next__()) # o
# 易混淆点:
print(c.__iter__().__next__()) # h
print(c.__iter__().__next__()) # h
print(c.__iter__().__next__()) # h
print(c.__iter__().__next__()) # h
print(c.__iter__().__next__()) # h
'''以上每一次都是重新迭代,迭代一次,结果都是h'''
2.3 for循环内部原理
for 变量名 in 可迭代对象:
循环体代码
l = [1, 2, 3, 4, 5, 6, 7]
# 要求:循环打印出列表中每个元素,但是,不能使用for循环,__next__ , next()
# 1.练习方式:
res = l.__iter__()
count = 0
while count < len(l):
print(next(res))
count += 1
# 2.for循环内部
# 2.1 可迭代对象要转为迭代器
res = l.__iter__()
while True:
'''2.2 肯定有一个语法检查错误,捕捉了'''
print(res.__next__())
'''for循环内部其实也报错了,只不过错误没让我们看见,内部处理了'''
"""
for循环内部执行流程:
1. 把关键字in后面的数据类型转为了迭代器 __iter__
2. 内部开始循环依次让迭代器对象调用__next__取值
3. next取值完毕之后也报错了,自动捕获并处理错误并且结束while循环
"""