# 可迭代对象: # 类型中申明了一个__iter__方法,同时该方法返回一个迭代器对象 # 能够用for循环的都是可迭代对象 # 列表、元组、字典、集合都是可迭代对象 # 迭代器: # 类型中申明了一个__next__方法 # for循环原理 # (1) 调用 in 后面对象的__iter__方法,获得一个迭代器对象iter # (2) 不断的调用迭代器对象iter的__next__方法将返回值赋值给给变量i,知道收到StopIteration退出循环 from typing import Counter l = [1,2,3] iter = l.__iter__() print(iter.__next__()) # 1 print(iter.__next__()) # 2 print(iter.__next__()) # 3 #print(iter.__next__()) # 只有三个值,第四个报错:StopIteration # 实现一个迭代器 l = [i for i in range(1,101)] #print(l) # 所有的数据都存在到列表内存中,若要存大量数据,内存不足 class MyIter(object): def __init__(self) -> None: self.n = 0 self.max = 5 def __iter__(self): return self def __next__(self): if self.n < self.max: self.n += 1 else: raise StopIteration return self.n obj = MyIter() obj.__iter__() obj.__next__() print(obj.__next__()) for i in obj: print(i) ################################################## # 可以拆开,将iter和next方法写在两个类里面 class Num5(object): def __iter__(self): return MyIter() class MyIter(object): def __init__(self) -> None: self.n = 0 self.max = 5 def __next__(self): if self.n < self.max: self.n += 1 else: raise StopIteration return self.n obj = Num5() for i in obj: print(i) ############################################### # 生成器: # 生成器是一个特殊的迭代器 def getNum(): print("*" * 20) count = 0 while count < 5: count += 1 yield count l = getNum() # 创建生成器对象,这个时候发现print("*" * 20) 没有被执行 print(l.__next__()) # 这个时候将执行print("*" * 20) print(l.__next__()) for i in l: print(i) # 生成器表达式 gen = (i for i in range(1,11)) print(gen) print(gen.__next__()) print(next(gen)) for i in gen: print(i) ################################################### def add(s, x): return x + s def gen(): for i in range(4): yield i base = gen() for n in [1, 10]: base = (add(i, n) for i in base) # 这个里面1是取不到的 # 由于n = 1的时候,还是一个迭代器对象,所以不会执行代码 # 只有当list(base)的时候才能调用n,所以n将会取值10 # 从而得到[20, 21, 22, 23] print(list(base))