面试:迭代器,生成器
实际开发:协程 gevent
可迭代对象:列表/字典/元组/字符串/集合/文件对象 ...
类似实际生活中看书的时候,看到哪一页就在那一页中放一个书签,
主要是为了快速翻到那一页,迭代就是类似于翻书的过程.每次都有一个工具将我们读到哪一页
这个位置记录下来.
迭代器的作用:帮助 我们记录迭代过程的工具.称之为迭代器.里面记录的是位置信息.
在每次遍历之后,会自动的向下移动一个位置.并记住这个位置.
用户直接找迭代器要即可,
记录遍历的位置信息.
记录迭代的位置信息.
iter(可迭代对象) 把第一个元素放进来,并返回迭代器(就是自己)
next(iter(可迭代对象))
if __name__ == '__main__': data = [1, 2, 3, 4, 5] # 遍历 --> 迭代 这个过程就是迭代 # for i in data: # print(i) # 模拟for循环的过程 # 取出对象中的迭代器 # 1.取出可迭代对象的首个元素,放入迭代器中,并返回迭代器 i = iter(data) # 2.不断 通过迭代器取出下一个元素的值,直到 迭代完成,抛出StopIteration: 停止迭代的异常 # print(next(iter(data))) print(next(i)) print(next(i)) print(next(i)) print(next(i)) print(next(i)) # print(next(i)) # 如果迭代完成,则抛出异常 StopIteration
迭代器实现for循环:
if __name__ == '__main__': data = [1, 2, 3, 4, 5] # for i in data: # print(i) # 模拟for 遍历的 过程 # 1.取出迭代器 it = iter(data) # 每次都是取出第一个元素 while True: # 通过迭代器取出下一个元素的值<返回值> try: # it = iter(data) # 每次都是取出第一个元素,不能放在这里,否则就是死循环. i = next(it) # 迭代器的返回值赋给i # 如果迭代完成,则抛出StopIteration异常 except Exception as e: print(e) break else: print(i)
自定义实现迭代器:
class FibIter: def __init__(self, n): self.n = n self.num1 = 1 self.num2 = 1 self.count = 0 def __iter__(self): """iter(对象):取出对象的迭代器 作为本对象 通过__iter()__返回一个迭代器""" return self # 类是迭代器,所以创建的对象就是可迭代对象 def __next__(self): """值 = next(迭代器) 作为本对象 通过__next__()反复返回下一个元素的值""" if self.count < self.n: ret = self.num1 # 打包/拆包 self.num1, self.num2 = self.num2, self.num1 + self.num2 self.count += 1 return ret else: raise StopIteration # n提前不准备数据,只是需要使用的时候才会去计算所需要的那一个,延迟计算. Python实现的延迟计算(也成为懒惰计算) if __name__ == '__main__': # 1 1 2 3 5 8 13 # 创建一个实例对象 f = FibIter(10) # 如果能够遍历 # 法1: # for i in f: # print(i) # 法2: it = iter(f) # 每次都是取出第一个元素 实际上是去调用__iter__()方法 自动调用魔法方法. while True: # 通过迭代器取出下一个元素的值<返回值> try: # it = iter(data) # 每次都是取出第一个元素,不能放在这里,否则就是死循环. i = next(it) # 迭代器的返回值赋给i 自动调用__next__() 魔法方法. # 如果迭代完成,则抛出StopIteration异常 except Exception as e: print(e) break else: print(i) """ 总结: 1.> 迭代器: 记录迭代的位置信息的对象 操作: 迭代器= iter(可迭代对象) --> 可迭代对象.__iter__() 下一个元素的值= next(迭代器) --> 迭代器.__next__() 判断: isinstance(对象,类型) 判断对象是否是xxx类型 返回值是True或者False isinstance(对象,迭代器类型) isinstance(对象,Iterator) # 首先要导入 from collections import Iterator 2.> 实现迭代器 魔法方法: Python 预先自定义功能的方法. __iter__()方法 提供迭代器<返回self 毛遂自荐> __next__()方法 提供下一个元素 可迭代对象: 可以被迭代的对象 判断:for循环遍历(偶尔使用还行) from collections import Iterable isinstance(obj,Iterable) # 判断一个对象是否是可迭代类型 结论:迭代器一定是可迭代对象 可迭代对象 不一定是迭代器 <只需要实现__iter__()方法提供迭代器> 面试: 迭代器需要实现那些方法? __iter__() __next__() 可迭代对象需要实现那些方法? __next__() 可以有,也可以没有 __iter__() -> 可迭代对象的标识 可迭代对象的范围更大<包含了迭代器> 迭代器和可迭代对象的区别 迭代器一定是可迭代对象/可迭代对象 不一定是迭代器 如何判断对象是否是可迭代对象/迭代器 isinstance(obj,Iterable) ---> 可迭代对象 isinstance(obj,Iterator) ---> 迭代器 示例: from collections import Iterator d = [1,2,3,4] isinstance(d,Iterator) Out[15]: False d1 = iter(d) isinstance(d1,Iterator) Out[15]: True from collections import Iterable isinstance(d,Iterable) Out[17]: True """