整体说明
- 在 Python 里,
iter()函数主要用于生成迭代器 - 迭代器用于遍历可迭代对象(像列表、元组、字典这样的),能逐个获取对象里的元素
- 用法可总结如下:
iter()函数的主要作用是把可迭代对象转变为迭代器- 迭代器通过
next()函数来获取下一个元素 - 可以通过自定义类并实现
__iter__()和__next__()方法来自定义迭代器 - 使用
StopIteration异常或者设置哨值能够终止迭代
iter()函数的基本用法
函数用法:
1
iter(iterable)
- 这里的
iterable可以是列表、元组、字符串、集合等可迭代对象
- 这里的
示例:遍历列表
1
2
3
4
5
6
7
8
9
10my_list = [1, 2, 3, 4, 5]
my_iter = iter(my_list)
# # 错误用法,会抛出异常
# for i in range(10):
# print(next(my_iter)) # 依次输出:1,2,3,4,5,第6次调用时直接抛出异常 StopIteration
# 正确用法
for i in my_iter:
print(i) # 依次输出:1,2,3,4,5 然后停止
自定义迭代器(无终止迭代)
- 借助
iter()函数,还能自定义迭代器,这需要在类中实现__iter__()和__next__()方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter)) # 输出:1
print(next(myiter)) # 输出:2
print(next(myiter)) # 输出:3
自定义迭代器(终止迭代)
- 在自定义迭代器时,可以使用
StopIteration异常来终止迭代1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 3:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x) # 依次输出1,2,3后停止(注意程序是自然退出的,不会抛出异常)
附录:Iterable 和 Iterator 的区别
- 可迭代对象(Iterable) :任何可以被
iter()函数调用并返回一个迭代器的对象- 常见例子:列表(list)、元组(tuple)、字符串(str)、字典(dict)、集合(set)等
- 可以用
for循环遍历,不存储迭代状态(即每次调用iter()都会生成一个新的迭代器) - 可以被多次迭代(每次都是新的迭代器)
- 迭代器(Iterator) :实现了
__next__()方法和__iter__()方法的对象- 常见例子:由
iter()函数返回的对象、生成器(generator)等 - 有“状态”,记录当前迭代位置
- 调用
next()方法会返回下一个元素,直到耗尽后抛出StopIteration - 只能迭代一次(无法重置,耗尽后失效)
__iter__()方法返回自身(所以迭代器也是一种可迭代对象)
- 常见例子:由
- 特别说明:DataLoader 本身是一个可迭代对象(iterable),而非一次性迭代器(iterator)
附录:特别说明 iter() 的第二个参数
iter()函数还有一种不太常见的用法,就是接收两个参数- 第一个参数得是个可调用对象(像函数)
- 第二个参数是哨值
- 当可调用对象返回的值等于哨值时,迭代就会停止
1
2
3
4
5
6
7
8
9
10
11
12
13def my_function():
value = input("请输入内容(输入 'q' 结束):")
return value
# 创建迭代器,当输入 'q' 时停止
my_iter = iter(my_function, 'q')
for value in my_iter:
print(f"你输入的是:{value}")
# 请输入内容(输入 'q' 结束):123
# 你输入的是:123
# 请输入内容(输入 'q' 结束):q
附录:for 循环和 __iter__ 函数的用法
- 在
for i in x循环中,x.__iter__()只会被调用一次 ,且该方法的返回值必须是一个 Iterator(迭代器)- 这属于 Python 迭代协议(Iteration Protocol)的核心要求
__iter__的调用 1 次后,循环的所有迭代过程,都基于__iter__返回的同一个迭代器__iter__的返回值要求:必须返回一个实现了迭代器协议的对象(即同时具有__iter__()和__next__()方法的对象)- 可迭代对象的
__iter__:“生产迭代器”(返回新的迭代器实例); - 迭代器的
__iter__:“暴露自己”(返回自己,因为自己就是 “干活的”) - 迭代器的
__next__(),真正用于返回下一个元素
- 可迭代对象的
- 支持
for循环的对象,一定是具有__iter__()函数的
原理拆解:for 循环的执行流程
for i in x的底层逻辑完全遵循迭代协议,步骤如下:- 1)调用
x.__iter__(),获取一个迭代器对象(记为it); - 2)反复调用
it.__next__(),每次返回的结果赋值给i,执行循环体; - 3)当
it.__next__()抛出StopIteration异常时,循环捕获该异常并正常终止(不会暴露给用户)
- 1)调用
- 注:整个过程中,
x.__iter__()只在第一步执行一次,后续所有迭代都依赖第一步返回的那个it迭代器