可迭代对象和迭代器
前言
对于刚刚进入python学习的小伙伴来说,可迭代对象和迭代器的概念有点难以理解,今天笔者想在此讲解下二者的联系和区别,有错误之处,还请各位大佬指正
一、什么是迭代?
迭代是访问集合元素的一种方式;我们把通过for…in…语句这样进行遍历的过程称为迭代
二、什么是可迭代对象(Iterable)
1.可迭代对象的定义
我们通常把可以通过for…in…语句进行遍历的对象,称之为可迭代对象(Iterable)
for i in range(5):
print(i, end=' ')
# 输出:0 1 2 3 4
# range(5)的返回值,就是一个可迭代对象
2.怎么判断一个对象是不是可迭代对象
可以通过isinstance方法来判断一个对象是不是可迭代对象
from collections.abc import Iterable
print(isinstance([], Iterable)) # True
print(isinstance('', Iterable)) # True
print(isinstance((), Iterable)) # True
print(isinstance(set(), Iterable)) # True
print(isinstance({}, Iterable)) # True
print(isinstance(range(5), Iterable)) # True
print(isinstance(4, Iterable)) # False
print(isinstance(True, Iterable)) # False
3.自定义可迭代对象
知道了怎么判断一个对象是不是可迭代对象之后,那创建对象的类要符合什么样的条件,才能使得他创建的对象是可迭代对象呢?
from collections.abc import Iterable
class A(object):
def __init__(self):
super().__init__()
class B(object):
def __init__(self):
super().__init__()
def __iter__(self):
pass
print(isinstance(A(), Iterable)) # False
print(isinstance(B(), Iterable)) # True
# 可以看出,B类与A类相比,只多了一个__iter__方法
一个实现了__iter__方法的类创建的对象,都是可迭代对象
然后尝试直接进行遍历:
class B(object):
def __init__(self):
super().__init__()
def __iter__(self):
pass
for i in B():
print(i)
# 运行会报错 -> TypeError: iter() returned non-iterator of type 'NoneType'
可见,单纯实现了__iter__并不支持进行遍历,__iter__对象还需要返回一个迭代器(Iterator),才可以遍历
三、什么是迭代器(Iterator)
1.迭代器的定义
迭代的过程中,迭代器起着,帮助我们记录迭代位置的作用,从而可以依次由前向后获取序列中的数据
我们在迭代一个可迭代对象的时候,就是先通过__iter__方法获取到该对象提供的迭代器,再通过这个迭代器,依次获取对象中的每一个数据
2.怎么判断一个对象是不是迭代器
可以通过isinstance方法来判断一个对象是不是迭代器
from collections.abc import Iterator
print(isinstance([], Iterator)) # False
print(isinstance(iter([]), Iterator)) # True
print(isinstance('', Iterator)) # False
print(isinstance(iter(''), Iterator)) # True
print(isinstance((), Iterator)) # False
print(isinstance(iter(()), Iterator)) # True
print(isinstance(set(), Iterator)) # False
print(isinstance(iter(set()), Iterator)) # True
print(isinstance({}, Iterator)) # False
print(isinstance(iter({}), Iterator)) # True
3.自定义迭代器
知道了怎么判断一个对象是不是迭代器之后,那创建对象的类要符合什么样的条件,才能使得他创建的对象是迭代器呢?
from collections.abc import Iterator
class A(object):
def __init__(self):
super().__init__()
class B(object):
def __init__(self):
super().__init__()
def __iter__(self):
pass
class C(object):
def __init__(self):
super().__init__()
def __iter__(self):
pass
def __next__(self):
pass
print(isinstance(A(), Iterator)) # False
print(isinstance(B(), Iterator)) # False
print(isinstance(C(), Iterator)) # True
# 可以看出,C类与A类相比,只多了__iter__方法和__next__方法
一个实现了__iter__方法和__next__方法的类创建的对象,都是迭代器
四、自定义可迭代对象和迭代器实现遍历
1.__next__方法的作用
前文讲过,__iter__方法可以提供一个迭代器,帮助我们,在迭代的过程中记录位置,而__next__方法的作用就是返回迭代时序列中的值,依次往后变化
2.自定义可迭代对象和迭代器实现遍历
接下来,我们自定义一个可迭代对象的类,和一个迭代器的类,实现自定义对象的迭代
class MyIterable(object):
def __init__(self):
pass
def __iter__(self):
my_iterator = MyIterator()
return my_iterator
class MyIterator(object):
def __init__(self):
self.list = [1, 2, 3]
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.list):
res = self.list[self.index]
self.index += 1
return res
else:
raise StopIteration
for i in MyIterable():
print(i, end=' ')
# 输出: 1 2 3
总结
总结要点如下:
1、用for循环遍历的对象一定是可迭代对象
2、只实现了__iter__方法的类创建的对象,是可迭代对象
3、实现了__iter__方法和__next__方法的类创建的对象,是迭代器
4、__iter__方法需要返回一个迭代器,用于在迭代过程中帮忙记录位置;__next__方法的返回值就是遍历过程中得到的值