python11 可迭代对象 、迭代器、生成器、生成器表达式--惰性设计(节省内存)

一、可迭代对象:实现__iter__()方法。可以用for循环获取

   for循环原理:

# 可迭代对象  -- 容器
list01  = [43,3,4,5,567]
# 迭代过程
# for item in list01:
#     print(item)

# 迭代原理
# 面试题:for循环的原理是什么?
#        答:1. 获取迭代器
#           2. 循环获取下一个元素
#           3. 遇到异常停止迭代

#        可以被for的条件是什么?
#        答:能被for的对象必须具备__iter__方法
#        答:能被for的对象是可迭代对象

#1. 获取迭代器
iterator = list01.__iter__()
#2. 循环获取下一个元素
while True:
    try:
        item = iterator.__next__()
        print(item)
    #3. 遇到异常停止迭代
    except StopIteration:
        break# 退出循环

二、迭代器:实现__next__()方法。for循环的item元素就是通过迭代器获取的

 1 """
 2     迭代器 4 """
 5 
 6 
 7 class Skill:
 8     pass
 9 
10 
11 class SkillManager:
12     """
13         技能管理器  可迭代对象
14     """
15 
16     def __init__(self):
17         self.__skills = []
18 
19     def add_skill(self, skill):
20         self.__skills.append(skill)
21 
22     def __iter__(self):
23         # 创建一个迭代器对象,并传递需要迭代的数据。
24         return SkillIterator(self.__skills)
25 
26 
27 class SkillIterator:
28     """
29         技能迭代器
30     """
31 
32     def __init__(self, target):
33         self.__target = target
34         self.__index = 0
35 
36     def __next__(self):
37         # 如果没有数据了,则抛出异常
38         if self.__index > len(self.__target) - 1:
39             raise StopIteration
40 
41         # 返回下一个数据
42         temp = self.__target[self.__index]
43         self.__index += 1
44         return temp
45 
46 
47 manager = SkillManager()
48 manager.add_skill(Skill())
49 manager.add_skill(Skill())
50 manager.add_skill(Skill())
51 
52 for item in manager:
53     print(item)
54 
55 iterator = manager.__iter__()
56 while True:
57     try:
58         item = iterator.__next__()
59         print(item)
60     except StopIteration:
61         break

三、生成器=可迭代对象+迭代器 。通过yield关键字实现

生成器中间原理过程 

 1 """
 2    迭代器 --> yield
 3    练习: 将迭代器版本的图形管理器改为yield实现.
 4         exercise03.py -->exercise06.py
 5 """
 6 
 7 
 8 class MyRange:
 9     def __init__(self, stop_value):
10         self.stop_value = stop_value
11 
12     def __iter__(self):
13         # return MyRangeIterator(self.stop_value) #之前 可迭代对象返回的,现在把迭代器集成到这
14         # 0 --> self.stop_value
15         # yield 作用: 将下列代码改为迭代器模式的代码.
16         # 生成迭代器代码的大致规则:
17         # 1. 将yield以前的语句定义在next方法中
18         # 2. 将yield后面的数据作为next方法返回值
19         number = 0
20         while number < self.stop_value:
21             yield number
22             number += 1
23 
24         # print("准备数据")
25         # yield 0
26         # print("准备数据")
27         # yield 1
28         # print("准备数据")
29         # yield 2
30         # # ...
31 
32 """
33 class MyRangeIterator:
34     def __init__(self, end_value):
35         self.__end_value = end_value
36         self.__number = 0
37 
38     def __next__(self):
39         if self.__number == self.__end_value:
40             raise StopIteration
41 
42         temp = self.__number
43         self.__number += 1
44         return temp
45 """
46 
47 # next一次,计算一次,返回一次。
48 # for item in MyRange(10):
49 #     print(item)
50 
51 my01 = MyRange(10)
52 iterator = my01.__iter__()
53 while True:
54     try:
55         item = iterator.__next__()
56         print(item)
57     except StopIteration:
58         break

生成器以及原理

 1 """
 2     yield --> 生成器
 3     练习:exercise07.py
 4 """
 5 """
 6 class MyRange:
 7     def __init__(self, stop_value):
 8         self.stop_value = stop_value
 9 
10     def __iter__(self):
11         number = 0
12         while number < self.stop_value:
13             yield number
14             number += 1
15 
16 my01 = MyRange(10)
17 
18 iterator = my01.__iter__()
19 while True:
20     try:
21         item = iterator.__next__()
22         print(item)
23     except StopIteration:
24         break
25 """
26 
27 """
28 # 生成器原理
29 class MyGenerator:
30     # 生成器 = 可迭代对象 + 迭代器
31     def __init__(self,stop_value):
32         self.begin = 0
33         self.stop_value = stop_value
34         
35     def __iter__(self):
36         return self
37 
38     def __next__(self):
39         if self.begin >= self.stop_value:
40             raise StopIteration
41             
42         temp = self.begin
43         self.begin+=1
44         return temp
45 """
46 
47 
48 def my_range(stop_value):
49     number = 0
50     while number < stop_value:
51         yield number
52         number += 1
53 
54 my01 = my_range(10)
55 print(type(my01), dir(my01))# dir 获取对象所有成员
56 
57 print(id(my01.__iter__()), id(my01))
58 
59 for item in my01:
60     print(item)

 四、生成器表达式

 1 """
 2     生成器表达式
 3     练习:exercise03.py
 4 """
 5 
 6 list01 = [3, "54", True, 6, "76", 1.6, False, 3.5]
 7 # 生成器函数
 8 def find01():
 9     for item in list01:
10         if type(item) == int:
11             yield item + 1
12 re = find01()
13 for item in re:
14     print(item)
15 
16 #  生成器表达式
17 # 此时没有计算,更没有结果
18 re = (item + 1 for item in list01 if type(item) == int)
19 # 一次循环,一次计算,一个结果
20 for item in re:
21     print(item)
22 
23 # 列表推导式
24 # 此时已经完成所有计算,得到所有结果
25 re = [item + 1 for item in list01 if type(item) == int]
26 # 只是获取所有结果
27 for item in re:
28     print(item)
29 
30 # 变量 = [itme for item in 可迭代对象 if 条件] 列表推导
31 # 变量 = {k,v for k,v in 可迭代对象 if 条件} 字典推导
32 # 变量 = {item for item in 可迭代对象 if条件} 集合推导
33 # 变量 = (item for item in 可迭代对象 if条件) 生成器表达式

猜你喜欢

转载自www.cnblogs.com/libotao/p/12730452.html