Python中可迭代对象并不是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )
方法或__getitem__( )
方法访问。
常见可迭代对象有list、tuple、dict、set、str等。
判断可迭代对象
使用isinstance()
判断一个对象是否可迭代
from collections import Iterable
print(isinstance([1,2,3,],Iterable))
显然[1,2,3]这个列表是个可迭代对象,返回True
class Myclass(object):
pass
myclass = Myclass
print(isinstance(Myclass,Iterable))
print(isinstance(myclass,Iterable))
我们创建一个类,可以发现,这个类是不可迭代的。
class Myclass(object):
def __iter__(self):
pass
myclass = Myclass
print(isinstance(Myclass,Iterable))
print(isinstance(myclass,Iterable))
但是我们给它加上__iter__()
方法后,这个类创建的对象就可以迭代了!
我们看一下list
类的源码,发现它也拥有__iter__()
方法。
class list(MutableSequence[_T], Generic[_T]):
# 省略一大部分
@overload
def __iter__(self) -> Iterator[_T]: ...
# 省略一大部分
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
可迭代对象的本质是其所属的类拥有__iter__()
方法。
iter(可迭代对象)
可以用来生成一个迭代器,next(迭代器)
可以获取迭代器中的下一个值,若已是最后一个,则StopIteration
。
for循环的本质就是先和获取iter()
迭代器,并自动返回next()
的值,直到捕获StopIteration
。
所以自己使用next()
时一定要记得捕获异常!
list = [0,1,2,3,4,5,6,7,8,9]
list_iterator = iter(list)
while True:
try:
print(next(list_iterator))
except:
break
这样也可以达到for i in [0,1,2,3,4,5,6,7,8,9]: print(i)
的效果
使用next()
就可以调用该类的__next__()
方法。
自定义迭代器和迭代对象
# 自定义可迭代对象
class MyList(object):
def __init__(self):
# 定义实例属性,创建用于保存数据的列表
self.items=list()
def __iter__(self):
# 向迭代器传参
mylist_iterator = MyIterator(self.items)
return mylist_iterator
def additem(self,data):
# 向迭代对象里面添加数据
self.items.append(data)
# 自定义迭代器
class MyIterator(object):
def __init__(self,items):
# 接收可迭代对象传来的数据
self.items = items
# 下标初始为0
self.index = 0
def __iter__(self):
...
def __next__(self):
# 判断是否越界
if self.index < len(self.items):
# 没越界:下标+1,返回值
data = self.items[self.index]
self.index+=1
return data
else:
# 越界:报错
raise StopIteration
if __name__=="__main__":
# 创建可迭代对象
mylist = MyList()
# 添加数据
mylist.additem(0)
mylist.additem(1)
mylist.additem(2)
mylist.additem(3)
# 循环输出
for value in mylist:
print(value)