迭代器

一、可迭代对象

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循环
"""

posted @ 2023-03-07 19:55  星空看海  阅读(26)  评论(0编辑  收藏  举报