一、迭代器:
1、迭代:每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
2、可迭代对象(iterable):
1)定义:具有__iter__函数的对象,可以返回迭代器对象。
2)语法:
3)原理:
3、迭代器对象(iterator):
1)定义:可以被next()函数调用并返回下一个值的对象。
2)语法:
3)说明及作用:
二、生成器(generator):
三、生成器函数:
四、基础代码:
代码1:
""" 可迭代对象:具有__iter__()方法,可以返回迭代器的对象. """ list01 = [2,434,5,6,8] # for item in list01: # print(item) # 面试题: # 能够被for循环的条件是:可迭代对象(具有__iter__()方法的对象) # for循环原理 # 1. 获取迭代器对象 # 2. 循环迭代(调用迭代器的__next__方法) # 3. 捕获StopIteration异常 #1. # iterator = list01.__iter__() #2. # item = iterator.__next__() # print(item) # # item = iterator.__next__() # print(item) # # item = iterator.__next__() # print(item) # # item = iterator.__next__() # print(item) # # item = iterator.__next__() # 最后一次 # print(item) # 3. # item = iterator.__next__()# StopIteration # print(item) # 1. 获取迭代器对象 iterator = list01.__iter__() while True: try:# 如果获取了全部元素,则执行except # 2. 获取下一个元素(迭代过程) item = iterator.__next__() print(item) # 3.停止迭代(StopIteration 错误) except StopIteration: break # 跳出循环体
代码2:
""" 迭代器 """ class Skill: pass class SkillIterator: """ 技能迭代器 """ def __init__(self, target): self.target = target self.index = 0 def __next__(self): # 如果索引越界 则抛出异常 if self.index > len(self.target) - 1: raise StopIteration() # 返回下一个元素 item = self.target[self.index] self.index += 1 return item class SkillManager: """ 可迭代对象 """ def __init__(self, skills): self.skills = skills def __iter__(self): # 创建迭代器对象 传递 需要迭代的数据 return SkillIterator(self.skills) #---------------以下是客户端代码--------------------- manager = SkillManager([Skill(), Skill(), Skill()]) # for item in manager.skills: for item in manager:# 获取manager对象中列表元素(获取manager对象的聚合类型对象元素) print(item) # iterator = manager.__iter__() # while True: # try: # item = iterator.__next__() # print(item) # except: # break
代码3:
""" 迭代器 --> yield """ class Skill: pass # class SkillIterator: # """ # 技能迭代器 # """ # def __init__(self, target): # self.target = target # self.index = 0 # # def __next__(self): # if self.index > len(self.target) - 1: # raise StopIteration() # item = self.target[self.index] # self.index += 1 # return item class SkillManager: def __init__(self, skills): self.skills = skills # def __iter__(self): # return SkillIterator(self.skills) def __iter__(self): """ 执行过程: 1.调用__iter__()方法不执行 2.调用__next__()方法时执行,到yield语句暂时离开. 3.再次调用__next__()方法时,从上次离开的代码开始执行,到yield语句暂时离开 4. 待执行完方法体,抛出StopIteration异常. 原理:如果方法体中包含yield关键字,那么会自动生成迭代器对象. 生成迭代器代码的大致规则: 1. 将yield关键字以前的代码,放到__next__方法中. 2. 将yield关键字以后的数据,作为__next__方法的返回值 """ # print("准备返回第一个元素") # yield self.skills[0] # 暂时离开点 再次执行点 # # print("准备返回第二个元素") # yield self.skills[1] # # print("准备返回第三个元素") # yield self.skills[2] for item in self.skills: yield item #---------------以下是客户端代码--------------------- manager = SkillManager([Skill(), Skill(), Skill()]) # for item in manager: # print(item) iterator = manager.__iter__() while True: try: item = iterator.__next__() print(item) except Exception as e: print(e) break
代码4:
""" yield --> 生成器函数 """ # class MyRange: # def __init__(self, stop): # self.stop = stop # # def __iter__(self): # start = 0 # while start < self.stop: # yield start # start += 1 # # for item in MyRange(5): # print(item) # 生成器函数 def my_range(stop): start = 0 while start < stop: yield start start += 1 # for item in my_range(5): # print(item) iter01 = my_range(5) for item in iter01: print(item)
五、练习实例:
练习1:
# 练习1:("悟空","八戒","沙僧","唐僧") # 使用while + 迭代器 获取元组所有元素 t01 = ("悟空", "八戒", "沙僧", "唐僧") iterator = t01.__iter__() while True: try: item = iterator.__next__() print(item) except: break # 练习2:{"张三丰":101,"张无忌":102,"赵敏":102} # 不使用for循环,获取字典所有元素. d01 = {"张三丰": 101, "张无忌": 102, "赵敏": 102} iterator = d01.__iter__() while True: try: key = iterator.__next__() print(key, d01[key]) except: break
练习2:
""" 练习:迭代员工管理器对象 """ class Employee: pass class EmployeeIterator: """ 迭代器 """ def __init__(self, target): self.target = target self.index = 0 def __next__(self): if self.index > len(self.target) - 1: raise StopIteration() item = self.target[self.index] self.index += 1 return item # 可迭代对象 class EmployeeManager: def __init__(self, employees): self.all_employee = employees def __iter__(self): # 返回迭代器 return EmployeeIterator(self.all_employee) manager = EmployeeManager([Employee(), Employee()]) # 需求:for循环自定义类的对象 # for item in manager: # print(item) # iterator = manager.__iter__() while True: try: item = iterator.__next__() print(item) except: break
练习3:
""" 参照下列代码,定义MyRange类,实现相同效果. """ # 15:40 class MyRangeIterator: def __init__(self, stop): self.stop = stop self.start = 0 def __next__(self): if self.start + 1 > self.stop: raise StopIteration() temp = self.start self.start += 1 return temp class MyRange: def __init__(self, stop): self.stop = stop def __iter__(self): # 创建迭代器对象 return MyRangeIterator(self.stop) # for item in range(5): # print(item)# # for item in MyRange(5): # print(item)#0 1 2 3 4 iterator = MyRange(5) for item in iterator: print(item) # # iterator = iterator.__iter__() # while True: # try: # item = iterator.__next__() # print(item) # except: # break
练习4:
""" 改造为yield实现 """ class Employee: pass # class EmployeeIterator: # """ # 迭代器 # """ # def __init__(self, target): # self.target = target # self.index = 0 # # def __next__(self): # if self.index > len(self.target) - 1: # raise StopIteration() # item = self.target[self.index] # self.index += 1 # return item # 可迭代对象 class EmployeeManager: def __init__(self, employees): self.all_employee = employees # def __iter__(self): # # 返回迭代器 # return EmployeeIterator(self.all_employee) def __iter__(self): for item in self.all_employee: yield item manager = EmployeeManager([Employee(), Employee()]) # 需求:for循环自定义类的对象 # for item in manager: # print(item) # iterator = manager.__iter__() while True: try: item = iterator.__next__() print(item) except: break
练习5:
""" 改造为yield实现 """ # class MyRangeIterator: # def __init__(self, stop): # self.stop = stop # self.start = 0 # # def __next__(self): # if self.start + 1 > self.stop: # raise StopIteration() # temp = self.start # self.start += 1 # return temp class MyRange: def __init__(self, stop): self.stop = stop # def __iter__(self): # # 创建迭代器对象 # return MyRangeIterator(self.stop) def __iter__(self): start = 0 while start < self.stop: yield start start += 1 iterator = MyRange(5) # for item in iterator: # print(item) # iterator = iterator.__iter__() while True: try: item = iterator.__next__() print(item) except: break
练习6:
""" 生成器函数练习 体会:方法/函数,需要向外返回多个结果时,使用生成器函数. 惰性操作/延迟操作 (生成器函数的"循环(next)一次,计算一次,返回一次") """ list01 = [23,3,4,556,677,68,8,98,98] # 练习1:在list01中,挑出所有偶数. # 要求:1)使用生成器函数实现 def get_even01(target): for item in target: if item % 2 == 0: yield item iter01 = get_even01(list01)# 没有执行方法体 for item in iter01:# 循环(next)一次,计算一次,返回一次 print(item) # def get_even02(target): # result = [] # for item in target: # if item % 2 == 0: # result.append(item) # return result # # iter01 = get_even02(list01)# 执行方法体,将所有结果存在内存中. # for item in iter01: # print(item) # 练习2:定义函数,选出所有女同学. class Student: def __init__(self,name,sex,age,score): self.name = name self.sex = sex self.age = age self.score = score def __str__(self): return "%s--%s--%d--%d"%(self.name,self.sex,self.age,self.score) list_stu = [ Student("张无忌","男",28,82), Student("赵敏","女",25,95), Student("周芷若","女",26,88), ] def find_woman(target): for item in target: if item.sex == "女": yield item for item in find_woman(list_stu): print(item) # 练习3:选出所有成绩大于90的学生 def find_by_score(target): for item in target: if item.score > 90: yield item for item in find_by_score(list_stu): print(item)