class iterator(): def __init__(self,lst): self.lst = lst def __iter__(self): return self def __next__(self,index=-1): if index >= len(self.lst): raise StopIteration else: index +=1 return self.lst[index] iter = iterator([1,2,3,11,66]) for i in iter: print(i)
问题1:
__next__
方法不应该接受任何参数,因为它是由迭代器协议调用的
__next__
方法应该没有参数。__next__
方法中使用了 index
参数,但没有正确初始化索引,误将默认值作为初始化,每次调用next(),index都变成-1,你是知道的,for循环里面就是一个iter,然后多个next组成,所以一直死循环打印self.lst[0]class iterator(): def __init__(self,lst,index=-1): self.lst = lst self.index = index def __iter__(self): return self def __next__(self) if self.index >= len(self.lst): raise StopIteration else: self.index +=1 return self.lst[self.index] iter = iterator([1,2,3,11,66]) for i in iter: print(i)
又出现问题了:报索引超出了范围,我的本意是超出范围后会自动raise StopIteration
原因:
__init__
方法中将 index
初始化为 -1
,这会导致在第一次调用 __next__
时,index
会直接加 1,变成 0,然后返回列表的第一个元素。这本身没有问题,但在检查索引是否超出范围时,你使用了 if self.index >= len(self.lst)
,这会导致在最后一次迭代时,index
已经等于列表长度,从而抛出 StopIteration
异常__next__
方法中先检查了索引是否超出范围,然后才递增索引。这会导致在最后一次迭代时,index
已经等于列表长度,此时递增后会超出范围
有两种解决方案: 列表长度 - 1 = 最大索引,即判断索引=列表长度就抛异常 继续保持在判断之后递增: 只需判断是否大于等于列表长度-1: def __next__(self): if self.index >= len(self.lst) -1: raise StopIteration else: self.index +=1 return self.lst[self.index]
或者在判断之前递增:
class Iterator:
def __init__(self, lst):
self.lst = lst
self.index = 0 # 初始化索引为 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.lst): # 检查索引是否超出范围
raise StopIteration
item = self.lst[self.index] # 获取当前索引的元素
self.index += 1 # 索引递增
return item