迭代概念
迭代(Iterate): 逐个取出容器里面每一个元素的过程。
python
lst = [10, 20, 30]
for item in lst:
print(item)
for循环遍历列表,逐个从列表取出元素,这个动作就叫做迭代。
- 可迭代对象(Iterable) :只要实现了
__iter__()方法,能被iter()函数调用,返回一个迭代器,就是可迭代对象。
常见可迭代对象:
list、tuple、str、dict、set、range、文件对象。特点:可以被 for 循环遍历,但它本身不是迭代器。
__iter__()是一个魔术方法,当调用iter()方法时,__iter__()会自动被调用
python
st = [10, 20, 30]
tup = ('张三', '李四', '王五')
d = {'name': '张三', 'age': 18}
str1 = 'Hello World'
num = 10
# 1. 可迭代对象内部实现了__iter__()方法,可以直接调用
lst.__iter__()
tup.__iter__()
d.__iter__()
str1.__iter__()
# num.__iter__() # 报错AttributeError,因为int类型没有实现__iter__()方法,不是可迭代对象
# 2. iter()函数,可以调用可迭代对象的__iter__()方法,返回一个迭代器
# iter() 方法是一个内置函数,可以调用可迭代对象的__iter__()方法,返回一个迭代器
iter(lst)
iter(tup)
iter(d)
iter(str1)
# iter(num) # 报错 TypeError,因为int类型没有实现__iter__()方法,不是可迭代对象
- 迭代器(Iterator)
迭代器是用来执行迭代的工具。 迭代器必须同时满足两个条件:
- 有
__iter__()方法:返回自身(迭代器自己) - 有
__next__()方法:返回下一个元素;没有元素时抛出StopIteration异常
可迭代对象调用__iter__()方法会得到迭代器:
python
lst = [10, 20, 30]
tup = ('张三', '李四', '王五')
d = {'name': '张三', 'age': 18}
str1 = 'Hello World'
num = 10
# 可迭代对象__iter__()方法,返回一个迭代器
print(lst.__iter__()) # <list_iterator object at 0x000001AD6881BFA0>
print(tup.__iter__()) # <tuple_iterator object at 0x00000265C85A0070>
# iter()函数调用可迭代对象的__iter__()方法,返回一个迭代器
print(iter(lst)) # <list_iterator object at 0x000001AD6881BFA0>
如果
iter(obj)能得到一个迭代器(iterator)那么obj就是可迭代对象
迭代器用用__next__()方法,每次调用都会根据当前的状态,返回下一个元素:
python
lst = [10, 20, 30]
it = iter(lst)
print(it.__next__()) # 10
print(it.__next__()) # 20
print(it.__next__()) # 30
# print(it.__next__()) # 报错 StopIteration,因为没有下一个元素了
__next__()方法也是魔术方法,等价于next(it)
每次调用next,迭代器会记住当前位置 ,返回下一个元素。 没有元素,抛出 StopIteration。
python
print(next(it))
print(next(it))
print(next(it))
# print(next(it)) # 报错 StopIteration,因为没有下一个元素了
- for循环的工作原理
python
lst = [10, 20, 30]
for item in lst:
print(item)
# 1. 获取到可迭代对象的迭代器
it = iter(lst)
# 2. 开启循环
while True:
try:
# 3. 获取写一个元素
item = next(it)
print(item)
except StopIteration:
# 4. 退出循环
break
for 循环本质就是自动调用 iter、next,自动捕获 StopIteration,简化手写 while + 异常代码。
- 迭代器也有__iter__()方法,并返回的是迭代器自身
python
lst = [10, 20, 30]
it = iter(lst)
# 这两个是一样的
print(it)
print(it.__iter__()) # <list_iterator object at 0x000001AD6881BFA0>
- 迭代器特点
迭代器单向、一次性:元素取完就没了,不能回头。
再调用 next 直接报错,想要重新遍历,必须重新iter()生成新迭代器。
python
lst = [10, 20, 30]
it = iter(lst)
print(next(it))
print(next(it))
print(next(it))
print(next(it)) # 报错 StopIteration,因为没有下一个元素了
# 想要再次遍历,就需要生成新迭代器
it2 = iter(lst)
print(next(it2))
print(next(it2))
print(next(it2))
it = iter(lst)
for item in it:
print(item)
# 迭代器是一次性、单向的,元素取完就没了,不能回头。
for item in it:
print(item)
!TIP
迭代器一定是可迭代对象(有
__iter__()方法),但是可迭代对象不一定是迭代器(不一定有__next__()方法)。