day18
# review """ 复习 函数式编程:以函数为中心 功能1(): 相同 不同1 功能2(): 相同 不同2 功能3(): 相同 不同3 变化点1(): 不同1 变化点2(): 不同2 变化点3(): 不同3 通用(参数): 相同 # 不同3() 参数() 通用(变化点1) 通用(lambda 参数:方法体) """ # demo01 """ python内置高阶函数 """ 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), ] # 需求:找出编号大于102的所有技能 for item in IterableHelper.find_all(list01,lambda item:item.id > 102): print(item) # 1.过滤器 for item in filter(lambda item:item.id > 102,list01): print(item) # 需求:找出技能列表中所有技能编号和技能名称 for item in IterableHelper.select(list01,lambda item:(item.id,item.name)): print(item) #2. 映射 for item in map(lambda item:(item.id,item.name),list01): print(item) # 需求:找出技能列表中获取攻击力最大的技能 print(IterableHelper.get_max(list01,lambda item:item.atk)) # 3. 取最大值max 取最小 min print(max(list01,key = lambda item:item.atk)) # 需求:对技能列表根据持续时间进行升序排列 # IterableHelper.order_by(list01,lambda item:item.duration) # for item in list01: # print(item) # IterableHelper.order_by_descending(list01,lambda item:item.duration) # for item in list01: # print(item) # 4. 排序 # -- 返回排序后的结果,不改变原有数据。 # -- 默认升序排列 # -- 通过reverse=True 进行降序排列 # for item in sorted(list01,key =lambda item:item.duration): # print(item) for item in sorted(list01,key =lambda item:item.duration,reverse=True): print(item) # demo02 """ 笛卡尔积 全排列 练习:exercise02 """ import itertools # 排列出所有扑克牌 13 * 4 --> 列表(52) # 扑克牌的数字 list_number = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"] # 扑克牌的花色 list_suit = ["红桃", "黑桃", "方片", "梅花"] # list_poker = [] # for number in list_number: # for suit in list_suit: # list_poker.append((number, suit)) # # print(len(list_poker), list_poker) # for item in itertools.product(list_number,list_suit): # print(item) result = tuple(itertools.product(list_number, list_suit)) print(len(result), result) # 排列出3个色子可以组成的所有数字6 * 6 × 6 --》 6**n # 色子(1 -- 6) 6 # list_result = [] # for x in range(1, 7): # for y in range(1, 7): # for z in range(1, 7): # list_result.append((x, y, z)) # print(len(list_result), list_result) result = tuple(itertools.product(range(1, 7), repeat=3)) print(len(result), result) # for item in itertools.product(range(1, 7),repeat=10): # print(item) # demo03 """ 排列 从n个元素中取出m个元素,并按照顺序进行排列. 公式:n! / (n-m)! """ import itertools # 7 个人 中取3个 # 7 * 6 * 5 * 4 * 3 * 2 * 1 # 4 * 3 * 2 * 1 tuple_person = ("男1号","男2号","男3号","女1号","女2号","女3号","女4号") print(7 * 6 * 5) result = tuple(itertools.permutations(tuple_person,3)) print(len(result),result) # demo04 """ 组合 从n个元素中取出m个元素 不考虑顺序的排列 练习:exercise04.py """ import itertools # 7 个人 中取3个 tuple_person = ("男1号", "男2号", "男3号", "女1号", "女2号", "女3号", "女4号") result = list(itertools.combinations(tuple_person, 3)) print(len(result), result) # demo05 """ 外部嵌套作用域 """ def fun01(): a = 10 def fun02(): b = 20 # print(a) # 访问外部嵌套作用域中的变量 # a = 30# 创建了局部变量a nonlocal a # 声明外部嵌套作用域变量 a = 30 # 再进行修改 fun02() print(a) fun01() # demo06 """ 闭包 内外函数的执行环境,称之为闭包 特点:外部函数执行过后,没有立即释放栈帧(等着内部函数使用). """ def fun01(): a = 10 print("fun01执行喽") # 要素1:有内嵌函数 def fun02(): # 要素2:访问外部变量 print("fun02执行喽", a) # 要素3:返回内部函数 return fun02 result = fun01() result()# 执行fun02 # demo07 """ 装饰器 练习:exercise06 """ def print_func_name(func): def wrapper(*args, **kwargs): print(func.__name__) return func(*args, **kwargs) return wrapper # 增加新功能:打印函数名称 # def print_func_name(func): # print(func.__name__) # print_func_name(print) @print_func_name def say_hello(): print("hello") @print_func_name def say_goodbye(): print("goodbye") say_hello() say_goodbye() # demo08 """ 装饰器 -- 推导过程 在不改变旧功能(进入后台,删除订单)基础上,为其增加新功能(验证权限) 练习:exercise07 """ def verif_permissions(func): # 2. * args 为了解决位置实参个数无限问题 def wrapper(*args,**kwargs):# * 将实参合为一个元组 # 新功能 print("验证权限") # 旧功能 # 3. 内部函数的返回值就是旧功能的返回值 return func(*args,**kwargs)# * 将实参拆分,与形参对应 return wrapper # 旧功能 @verif_permissions# enter_background = verif_permissions(enter_background) def enter_background(login_id,pwd): print(login_id,"进入后台") @verif_permissions def delete_order(): print("删除订单") return True # # 拦截 = 新 + 旧 # enter_background = verif_permissions(enter_background) # # delete_order = verif_permissions(delete_order) # 1.调用的是内部函数 enter_background("abc",pwd = "123") print(delete_order()) # exercise01 """ 练习: 使用内置高阶函数实现: 1. ([1,1],[2,2,2],[3,3,3]) 获取元组中长度最大的列表 2. 在老婆列表列表,获取所有名称与身高 3. 在老婆列表中,获取所有体重大于50的老婆 4. 对老婆列表,根据身高进行降序排列 5. 获取所有身高大于1.6的老婆名称和身高. """ class Wife: def __init__(self, name="", weight=0.0, height=0.0): self.name = name self.weight = weight self.height = height def __str__(self): return self.name def __repr__(self): return "Wife(" + self.name + ")" list01 = [ Wife("翠花", 60, 1.5), Wife("赵敏", 45, 1.7), Wife("铁扇公主", 55, 1.65), Wife("如花", 40, 1.6), ] # 1. tuple01 = ([1, 1], [2, 2, 2], [3, 3, 3]) print(max(tuple01, key=lambda item: len(item))) # 2. # 惰性操作 --> 立即操作 result = tuple(map(lambda item: (item.name, item.height), list01)) print(result[-2:]) # 3. result = tuple(filter(lambda item: item.weight > 50, list01)) print(result) # 4. result = sorted(list01, key=lambda item: item.height, reverse=True) print(len(result), result) # 5. for item in map(lambda item: (item.name, item.height), filter(lambda item: item.height > 1.6, list01)): print(item) # 获取满足条件的所有人 # result = filter(lambda item:item.height > 1.6,list01) # # 获取人的某些信息 # for item in map(lambda item:(item.name,item.height),result): # print(item) # exercise02 # 练习1:在3男,4女中,选出2个人的所有可能性. # ("男1号","男2号","男3号") # ("女1号","女2号","女3号","女4号") import itertools tuple_man = ("男1号", "男2号", "男3号") tuple_woman = ("女1号", "女2号", "女3号", "女4号") result = tuple(itertools.product(tuple_man,tuple_woman)) print(len(result),result) # exercise03 import itertools # 练习1: 计算在4张牌中排列4中的可能性 from common.iterable_tools import IterableHelper tuple_poker = ("红桃3", "黑桃2", "梅花5", "大王") list_result = list(itertools.permutations(tuple_poker, 4)) print(len(list_result), list_result) # 练习2:"012345",可以组成多少个不重复的5位偶数 # list_result = list() # print(len(list_result), list_result) for item in filter(lambda item: item[0] != "0" and int(item[-1]) % 2 == 0, itertools.permutations("012345", 5)): # ('1', '0', '2', '3', '4') -->"10234" --> 10234 print(int("".join(item))) # exercise04 import itertools # 练习1: 计算在4张牌中组合2张中的可能性 tuple_poker = ("红桃3", "黑桃2", "梅花5", "大王") # for item in itertools.combinations(tuple_poker,2): # print(item) # 练习2: # 药品调剂 # 分为3种药品,共取出100例粒,要求:没种必须都要有. # 计算所有调剂方式 # 提示:思考共取出5粒如何实现 contents = 100 for item in itertools.combinations(range(1, contents), 2): # item 是 (1, 2) 板子的位置 # (2,4) for i in range(item[0]): print("A药品", end=" ") for i in range(item[1] - item[0]): print("B药品", end=" ") for i in range(contents - item[1]): print("C药品", end=" ") print() # exercise05 """ 闭包应用 逻辑连续 装饰器 """ # 压岁钱 def give_gife_money(money): def child_buy(target, price): nonlocal money if money >= price: money -= price print("孩子买了%s,花了%.1f钱" % (target, price)) else: print("钱不够了,呜呜呜~") return child_buy action = give_gife_money(10000) action("变形金刚", 200) action("天安门模型", 500) action("手机", 12000) # exercise06 """ 在不改变旧功能(进入后台,删除订单)基础上,为其增加新功能(验证权限) """ def verif_permissions(func): def wrapper(*args, **kwargs): print("验证权限") return func(*args, **kwargs) return wrapper @verif_permissions def enter_background(): print("进入后台") @verif_permissions def delete_order(): print("删除订单") enter_background() delete_order() # exercise07 """ 在不改变旧功能(fun01,fun02)基础上,为其增加新功能(打印方法执行时间) 公式:执行时间 = 开始后 - 开始前 """ import time def print_execute_time(func): def wrapper(*args, **kwargs): start_time = time.time() # 旧功能 result = func(*args, **kwargs) stop_time = time.time() # 新功能 print(stop_time - start_time) return result return wrapper @print_execute_time def fun01(): for i in range(10): pass @print_execute_time# fun02 = print_execute_time(fun02) def fun02(): for i in range(1000000): pass fun01() fun02() exercise.txt # review 作业 1. 三合一 2. 当天练习独立完成 3. 每个灯泡都有"亮","灭"两种模式, 请打印出30个灯泡所有可能的模式 4. 年会节目有: "舞蹈1","舞蹈2","舞蹈3","相声1","相声2","歌曲1","歌曲2","歌曲3","歌曲4" 请打印出节目所有排列的方案 要求:相同节目不能挨着. 5. 阅读: 程序员的数学 重构 HeadFirst 设计模式