可迭代对象(iterable)
定义
实现了__iter__方法的对象称为可迭代对象,在python中,可迭代对象有字符串、列表、元组、字典、集合等
创建可迭代对象
class MyNumbers:
def __init__(self):
self.a = 1
def __iter__(self):
return self
my_numbers = MyNumbers()
判断
判断对象是否是可迭代对象
from collections.abc import Iterable
print(isinstance("123", Iterable)) #字符串:True
print(isinstance([1, 2, 3], Iterable)) #列表:True
print(isinstance((1, 2, 3), Iterable)) #元组:True
print(isinstance({"a": 1, "b": 2}, Iterable)) #字典:True
print(isinstance({1, 2, 3}, Iterable)) #集合:True
print(isinstance(open("test.txt", "r"), Iterable)) #文件:True
print(isinstance(my_numbers, "r"), Iterable)) #my_numbers对象:True
也可以去源码里查看,比如源码里的list类实现了__iter__方法
迭代器(iterator)
定义
实现了__iter__和__next__方法的对象称为迭代器,__iter__返回一个特殊的迭代器对象self,__next__返回下一个可用元素,如果没有元素,会抛出StopIteration异常
内置的迭代器
map()、zip()、enumerate()、filter()、文件对象等都是迭代器
创建迭代器
class MyNumbers:
def __init__(self):
self.a = 1
def __iter__(self):
return self
def __next__(self):
x = self.a
self.a += 1
return x
my_numbers = MyNumbers()
print(next(my_numbers)) #1
print(next(my_numbers)) #2
print(next(my_numbers)) #3
判断
from collections.abc import Iterator
print(isinstance(my_numbers, Iterator)) #my_numbers对象:True
特点
- 迭代器是一个可以记住遍历位置的对象
- 迭代器对象从集合的第一个元素可以访问,直到所有的元素被访问完结束
- 迭代器只能往前不能后退
- 迭代器有两个基本的方法:iter()和next()
可迭代对象和迭代器的关系
用可迭代对象创建迭代器
可迭代对象实现了__iter__方法,但没有实现__next__方法,实际上可迭代对象调用iter()方法时,它会自动调用__iter__方法,而__iter__方法的作用是返回一个特殊的迭代器,因此实现了用可迭代对象创建迭代器
用列表创建迭代器
L = [1, 2, 3]
I = iter(L)
print(next(I))
print(next(I))
print(next(I))
print(next(I)) #没有下一个元素,抛出异常
print(next(I))
# 运行结果
Traceback (most recent call last):
File "E:/virtual_workshop/everyday/test/iterators.py", line 80, in <module>
print(next(I))
StopIteration
1
2
3
为了避免异常的情况,可以使用for或者next加异常捕获来遍历元素
for循环
L = [1, 2, 3]
I = iter(L)
for i in I:
print(i, end=" ")
# 运行结果
1 2 3
next加异常捕获
import sys
L = [1, 2, 3]
I = iter(L)
while True:
try:
print(next(I), end=" ")
except StopIteration:
sys.exit()
# 运行结果
1 2 3
用字典创建迭代器
D = {"a":1, "b": 2, "c": 3}
I = iter(D)
for i in I:
print(i, end=" ")
# 运行结果
a b c
字典中有一个迭代器(但不能说字典本身就是迭代器),在迭代环境中,会自动一次返回一个key
D = {"a":1, "b": 2, "c": 3}
for key in D:
print(key, end=" )
# 运行结果
a b c
关系
- 迭代器一定是可迭代的,但可迭代对象不是迭代器
- 可以用可迭代对象创建迭代器
- 可迭代对象必须实现__iter__方法,不能实现__next__方法
- 可迭代对象与迭代器都有__iter__方法,但可迭代对象的__iter__用于实例化一个迭代器对象,而迭代器中的__iter__用于返回迭代器本身,与__next__共同完成迭代器的迭代
参考文章
《Python3 迭代器与生成器》
《python3 迭代器》
《Python3学习笔记(十四):可迭代对象、迭代器和生成器》
《如何理解Python中的可迭代对象、迭代器和生成器》