迭代器与生成器 # 迭代是python最强大的功能之一 是访问元素集合的方式之一 # 迭代器:迭代器是一个可以记住遍历位置的对象 # 迭代器对象 从集合的第一个元素开始访问,直到所有的元素访问结束 # 迭代器只能往前 不能后退 # # 迭代器有两个基本的方法:iter()和next() # 字符串 列表 元组对象都可以用于创建迭代器 # iter()可以用来创建迭代器 # next()可以用来依次获取迭代器内的元素 每次按顺序拿一个 # list1 = [1,2,3,6,7,9,7] it = iter(list1) # 创建迭代器对象 print(it) #<list_iterator object at 0x000002008DFA9518> print(next(it)) # 1 print(next(it)) # 2 print(next(it)) # 3 print(next(it)) # 6 print(next(it)) # 7 print(next(it)) # 9 print(next(it)) # 7 print(next(it)) #报错 StopIteration # # 迭代器对象可以for循环遍历 for i in it: print(i) # # 也可以使用next()函数打印 while True: try: print(next(it)) except StopIteration as e: break # # 创建一个迭代器需要用到两个方法__iter__()和__next__() # __iter__():方法需要返回对象本身:self # __next__(): 返回下一个数据 如果限制迭代次数 则需要抛出StopIteration异常用来结束迭代 # class Myiterator(): def __iter__(self): self.num = 0 return self #返回未被实例化的对象 def __next__(self): self.num += 1 return self.num if __name__ == '__main__': p = Myiterator() #创建迭代器对象 #使用iter方法转换为迭代器对象 it1 = iter(p) print(next(it1)) #1 print(next(it1)) #2 #使用for循环遍历 for循环内部逻辑,for循环可以遍历可迭代对象 在循环内部先执行__iter__方法 在通过__next__方法逐步取值 for i in it1: print(i) #没有限制迭代次数 导致for循环进入无限循环 # # 限制迭代次数 class Myiterator(): def __iter__(self): self.num = 0 return self #返回未被实例化的对象 def __next__(self): self.num += 1 if self.num == 10: raise StopIteration #等于10时 触发异常结束迭代 else: return self.num # if __name__ == '__main__': p = Myiterator() #创建迭代器对象 #使用iter方法转换为迭代器对象 it1 = iter(p) for i in it1: print(i) #1-9 # # 生成器:是一种特殊的迭代器 # 生成器返回保留关键字yield的值 # def func1(): yield 1 yield 2 yield 3 # 创建生成器对象 # (内部调用了生成器类generator创建的对象, # 生成器类generator也声明了__iter__()和__next__()方法) it1 = func1() print(next(it1)) #1 print(next(it1)) #2 print(next(it1)) #3 print(next(it1)) #报错StopIteration # 也可以使用for循环遍历 for i in it1: print(i) # # 利用生成器函数实现斐波那契数列 # 调用生成器函数 返回一个迭代器对象 def fbnq(n): a = 0 b = 1 c = 0 while True: if c > n : return yield a #第一次a的值为a = 0 第二次 a=1 # 双向复制可以理解为 a =b b=a+b 每一次迭代更新a和b的值 a,b = b, a + b #第一次a =1 b = 1 第二次 a=1 b=2 第三次 a = 2 b=3 第四次 a=3 b=5 c += 1 #控制迭代次数 f = fbnq(10) while True: try: print(next(f),end=' ') #0 1 1 2 3 5 8 13 21 34 55 except StopIteration: break