day17
# review """ 复习 迭代 iter 可迭代对象iterable:包含__iter__()方法 作用:能够被for 迭代器对象iterator:包含__next__()方法 作用:以【一种】方式获取容器【多种数据结构】的下一个元素 生成器 可迭代对象 + 迭代器对象 生成器函数 def 函数名称(): ... yield 数据 ... for item in 函数名称(): itme 存储的是yield后面的数据 生成器表达式 结果 = (对item处理 for item in 可迭代对象 if 条件) for item in 结果: ... """ str01 = "大家好,才是真的好." list01 = [23,34,4,5] # for item in str01: # print(item) # 书写for循环的快捷键: iter + 回车 +tab # demo01 """ 函数式编程 -- 函数作为参数 面向对象编程:考虑问题从对象角度出发 面向过程编程:考虑问题从实现(步骤)角度出发 面向函数编程:考虑问题从函数角度出发(不是架构设计思想) 用在某个类或者某个函数中(局部). """ def fun01(): print("fun01执行喽") # 1. 函数可以赋值给变量 a = fun01 # 通过变量调用函数 a() # 2. 将函数作为参数传递 def fun02(func): print("fun02执行喽") func() # fun01() fun02(fun01) # demo02 """ """ list01 = [4, 54, "65", 75, 8, "9", "b"] # 需求1:找出所有偶数 def find01(): for item in list01: if type(item) == int and item % 2 == 0: yield item # 需求2:找出所有字符串 def find02(): for item in list01: if type(item) == str: yield item # 需求3:找出所有大于10的整数 def find03(): for item in list01: if type(item) == int and item > 10: yield item # "封装" : 拆分变化点 # "变化的" def condition01(item): return type(item) == int and item % 2 == 0 def condition02(item): return type(item) == str def condition03(item): return type(item) == int and item > 10 """ # "继承":抽象变化点 --> 统一变化 --> 隔离变化 # "不变的" -----> 万能查找 def find(func_condition): for item in list01: # if condition01(item): if func_condition(item): yield item # “多态”:调用父,执行子。 # 不变的 + 变化的 for item in find(condition03): print(item) """ from common.iterable_tools import IterableHelper for item in IterableHelper.find_all(list01,condition01): print(item) # demo03 """ lambda:匿名函数 lambda 参数:方法体 注意: 方法体只能有一句话 方法体不支持赋值语句 15:25 上课 """ # 普通方法 def fun01(): print("fun01执行喽") fun01() # 无参数,无返回值 a = lambda: print("匿名方法执行喽") a() # 有参数,无返回值 def fun02(a, b, c): print("fun02执行喽", a, b, c) fun02(1, 2, 3) b = lambda a, b, c: print("匿名方法执行喽", a, b, c) b(1, 2, 3) # 有参数,有返回值 def fun03(a, b): return a > b print(fun03(1, 2)) # lambda 方法体只能有一句话 c = lambda a, b: a > b print(c(1, 2)) def fun04(obj): obj[0] = 100 list01 = [1] fun04(list01) print(list01) # lambda 方法体不支持赋值语句 # d = lambda obj:obj[0] = 100 # common 文件夹 # iterable_tools.py """ 可迭代对象常用工具 """ class IterableHelper: """ 可迭代对象助手 """ # 静态方法:函数(不需要操作实例/类数据) --> 方法 @staticmethod # 为了不隐式(自动)传参(self/cls) def find_all(iterable_target, func_condition): """ 在可迭代对象中,根据指定条件搜索全部元素. :param iterable_target:需要搜索的可迭代对象 :param func_condition:需要判断的条件 :return:生成器对象,存储满足条件的结果. """ for item in iterable_target: if func_condition(item): yield item @staticmethod def find_single(iterable_target, func_condition): """ 在可迭代对象中,根据指定条件搜索单个元素. :param iterable_target:需要搜索的可迭代对象 :param func_condition:需要判断的条件 :return:满足条件的结果. """ for item in iterable_target: if func_condition(item): return item @staticmethod def get_count(iterable_target, func_condition): """ 在可迭代对象中,查找满足条件的数量. :param iterable_target:需要搜索的可迭代对象 :param func_condition:需要判断的条件 :return:int类型,满足条件的数量. """ count = 0 for item in iterable_target: if func_condition(item): count += 1 return count @staticmethod def sum(iterable_target, func_handle): """ 在可迭代对象中,根据指定逻辑累加其中的元素. :param iterable_target:需要累加的数据(可迭代对象) :param func_condition:需要累加的逻辑(方法/函数) :return:累加结果 """ sum_value = 0 for item in iterable_target: sum_value += func_handle(item) return sum_value @staticmethod def is_exists(iterable_target, func_condition): """ 在可迭代对象中,根据指定条件判断是否存在元素. :param iterable_target:需要搜索的数据(可迭代对象) :param func_condition:需要判断的条件(方法/函数) :return:是否存在(bool类型)。 """ for item in iterable_target: # if item.atk > 50: if func_condition(item): return True return False @staticmethod def get_max(iterable_target, func_handle): """ 在可迭代对象中,根据指定条件查找最大元素 :param iterable_target:需要搜索的数据(可迭代对象) :param func_condition:需要判断的条件(方法/函数) :return:最大的元素 """ max = iterable_target[0] for i in range(1, len(iterable_target)): # if max.atk < iterable_target[i].atk: if func_handle(max) < func_handle(iterable_target[i]): max = iterable_target[i] return max @staticmethod def select(iterable_target, func_handle): """ 在可迭代对象中,根据指定逻辑映射元素 :param iterable_target:需要搜索的数据(可迭代对象) :param func_condition:需要处理的逻辑(方法/函数) :return: """ # result = [] # for item in iterable_target: # # result.append( (item.name,item.atk)) # result.append(func_handle(item)) # return result for item in iterable_target: yield func_handle(item) @staticmethod def order_by(iterable_target, func_condition): for r in range(len(iterable_target) - 1): for c in range(r + 1, len(iterable_target)): # if iterable_target[r].atk > iterable_target[c].atk: if func_condition(iterable_target[r]) > func_condition(iterable_target[c]): iterable_target[r], iterable_target[c] = iterable_target[c], iterable_target[r] # 在可迭代对象中,根据指定条件查找最小元素get_min @staticmethod def get_min(iterable_target, func_condition): min_value = iterable_target[0] for i in range(1, len(iterable_target)): # if min_value.atk > iterable_target[i].atk: if func_condition(min_value) > func_condition(iterable_target[i]): min_value = iterable_target[i] return min_value # 根据指定条件对可迭代对象进行降序排列order_by_descending @staticmethod def order_by_descending(iterable_target, func_condition): for r in range(len(iterable_target) - 1): for c in range(r + 1, len(iterable_target)): if func_condition(iterable_target[r]) < func_condition(iterable_target[c]): iterable_target[r], iterable_target[c] = iterable_target[c], iterable_target[r] # 在可迭代对象中,根据指定条件删除元素delete_all @staticmethod def delete_all(iterable_target,func_condition): # [w01,w02,w03] for i in range(len(iterable_target)-1,-1,-1): # if iterable_target[i].weight < 40: if func_condition(iterable_target[i]): del iterable_target[i] # exercise01 """ 练习1: 1. 创建技能类(编号、名称、攻击力、持续时间、攻击间隔) 2. 创建技能列表(不少于4种技能) 3. 根据函数式编程思想完成以下功能: -- 功能1:定义查找编号是102的技能对象 -- 功能2:定义查找名称是"辟邪剑法"的技能对象 (如果重名,只查找第一个) -- 功能3:定义查找持续时间大于10秒的单个技能对象 (如果有多个,只查找第一个) 步骤: (1)先定义3个函数实现3个功能. (2)“封装”:拆分变化点、提取稳定的代码. (3)"继承":在稳定的代码中抽象变化(提取成参数) (4)"多态":将稳定的代码与变化的代码相结合. 练习2:将find_single函数,移置IterableHelper类中 练习3: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,查找编号大于101的技能数量 -- 功能2:定义函数,查找攻击力在30-80之间的技能数量 步骤: (1)先定义2个函数实现2个功能. (2)“封装”:拆分变化点、提取稳定的代码. (3)"继承":在稳定的代码中抽象变化(提取成参数) (4)"多态":将稳定的代码与变化的代码相结合. (5)将稳定的代码,移置IterableHelper类中命名为get_count 练习4: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,计算所有技能的攻击力总合 -- 功能2:定义函数,计算所有技能的持续时间总合 步骤: (1)先定义2个函数实现2个功能. (2)“封装”:拆分变化点、提取稳定的代码. (3)"继承":在稳定的代码中抽象变化(提取成参数) (4)"多态":将稳定的代码与变化的代码相结合. (5)将稳定的代码,移置IterableHelper类中命名为sum (6)使用lambda调用IterableHelper类中的sum 练习5: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,判断技能列表中是否存在功能力大于50的技能 -- 功能2:定义函数,判断技能列表中是否存在持续时间为0的技能 步骤: (5)将稳定的代码,移置IterableHelper类中命名为is_exists (6)使用lambda调用IterableHelper类中的is_exists 练习6: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,获取技能列表中攻击力最强的技能 -- 功能2:定义函数,获取技能列表中攻间隔最长的技能 步骤: (5)将稳定的代码,移置IterableHelper类中命名为get_max (6)使用lambda调用IterableHelper类中的get_max 练习7: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,获取技能列表中技能名称与攻击力 -- 功能2:定义函数,获取技能列表中攻击力与攻击间隔与持续时间 步骤: (5)将稳定的代码,移置IterableHelper类中命名为select (6)使用lambda调用IterableHelper类中的select 思考: 如何获取第一个/最后一个/后三个 练习8: 根据函数式编程思想完成以下功能: -- 功能1:定义函数,根据攻击力对技能列表进行升序排列 -- 功能2:定义函数,根据持续时间对技能列表进行升序排列 步骤: (5)将稳定的代码,移置IterableHelper类中命名为order_by (6)使用lambda调用IterableHelper类中的order_by """ from common.iterable_tools import IterableHelper class Skill: def __init__(self, id, name, atk, duration, atk_interval): self.id = id self.name = name self.atk = atk self.duration = duration self.atk_interval = atk_interval # 对象 --> str def __str__(self): return "%d -- %s -- %.1f -- %.1f --%.1f" % (self.id, self.name, self.atk, self.duration, self.atk_interval) # 重写对象比较逻辑 # def __eq__(self, other): # 如果编号相同,就认为相同 # return self.id == other.id list01 = [ Skill(101, "葵花宝典", 50, 0, 0), Skill(102, "降龙十八掌", 80, 12, 1), Skill(103, "黯然销魂掌", 90, 15, 0.5), Skill(104, "辟邪剑法1", 70, 0, 0), Skill(104, "辟邪剑法2", 70, 0, 0), ] print(list01[3] == list01[4]) # false # 练习1 # (1)先定义3个函数实现3个功能. def find_single01(): for item in list01: if item.id == 102: return item def find_single02(): for item in list01: if item.name == "辟邪剑法": return item def find_single03(): for item in list01: if item.duration > 10: return item # (2)“封装”:拆分变化点、提取稳定的代码. def condition01(item): return item.id == 102 def condition02(item): return item.name == "辟邪剑法" def condition03(item): return item.duration > 10 """ # (3)"继承":在稳定的代码中抽象变化(提取成参数) def find_single(func_condition): for item in list01: # if item.duration > 10: # if condition03(item): if func_condition(item): return item # (4)"多态":将稳定的代码与变化的代码相结合. print(find_single(condition02)) print(find_single(condition01)) """ # 练习2 print(IterableHelper.find_single(list01,condition01)) # 练习3 def get_count01(): count = 0 for item in list01: if item.id > 101: count +=1 return count def get_count02(): count = 0 for item in list01: if 30 <= item.atk <= 80: count +=1 return count def condition01(item): return item.id > 101 def condition02(item): return 30 <= item.atk <= 80 """ def get_count(func_condition): count = 0 for item in list01: # if condition02(item): if func_condition(item): count +=1 return count """ print(IterableHelper.get_count(list01,condition01)) print(IterableHelper.get_count(list01,lambda item:item.id > 101)) # 练习4: """ # -- 功能1:定义函数,计算所有技能的攻击力总合 def sum01(): sum_value = 0 for item in list01: sum_value += item.atk return sum_value # -- 功能2:定义函数,计算所有技能的持续时间总合 def sum02(): sum_value = 0 for item in list01: sum_value += item.duration return sum_value def handle01(item): return item.atk def handle02(item): return item.duration def sum(func_handle): sum_value = 0 for item in list01: # 先用 sum_value += func_handle(item) return sum_value """ print(IterableHelper.sum(list01,lambda element: element.atk)) # 练习5: print(IterableHelper.is_exists(list01,lambda item:item.atk > 50)) # 练习6: print(IterableHelper.get_max(list01,lambda item:item.atk)) # 练习7: result = IterableHelper.select(list01,lambda item:(item.name,item.atk)) # 生成器不支持 索引/切片查找 result[0] # for item in result[-3:]: # print(item) # 解决方案: # 迭代生成器 # 将惰性操作(节省内存) --> 立即操作(灵活获取结果) result = tuple(result) print(result[-1]) # 作业: IterableHelper.delete_all(list01,lambda item:item.duration ==0) for item in list01: print(item) exercise.txt day17作业 1. 三合一 2. 当天练习独立完成 3. 在IterableHelper类中,增加如下功能: 在可迭代对象中,根据指定条件查找最小元素get_min 根据指定条件对可迭代对象进行降序排列order_by_descending 在可迭代对象中,根据指定条件删除元素delete_all 4. 阅读: 重构 HeadFirst 设计模式