定义:用一系列函数解决问题。
高阶函数:将函数作为参数或返回值的函数。
"""
函数式编程 语法
"""
def fun01():
print("fun01执行喽")
#调用方法,执行方法体
re1 = fun01()
print(re1)
#将函数赋值给变量
re2 = fun01
#通过变量,调用函数
re2()
def fun02():
print("fun02执行喽")
#将函数作为函数的参数进行传递
#好处:将一个函数的代码(fun02/fun01),注入到另外一个函数中(fun03)。
def fun03(func):
print("fun03执行喽")
func()
fun03(fun01)
fun03(fun02)
"""
函数式编程 思想
"""
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
"""
技能信息
:param id:技能编号
:param name:技能名称
:param atk_ratio: 攻击比例
:param duration: 持续时间
"""
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duraftion = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duraftion)
list_skill = [
SkillData(101, "乾坤大挪移",5, 10),
SkillData(102, "降龙十八掌", 8, 5),
SkillData(103, "葵花宝典",10,2),
]
def find01():
for item in list_skill:
if item.atk_ratio > 6 :
yield item
def find02():
for item in list_skill:
if 4 < item.duraftion < 11:
yield item
def find04():
for item in list_skill:
if len(item.name)> 4 and item.duraftion <6 :
yield item
#"封装"(分而治之,变而疏之)
#将每个变化的条件,单独定义在函数中。
def condition01(item):
return item.atk_ratio > 6
def condition02(item):
return 4 < item.duraftion < 11
def condition03(item):
return len(item.name)> 4 and item.duraftion <6
#"继承"(隔离变化)
def find(func_condition):
"""
通用的查找方法
:param func_condition:查找条件,函数类型
函数名(变量)--》返回值bool类型
"""
for item in list_skill:
#"多态":调用父(变量),执行子(具体函数)
if func_condition(item):
yield item
for item in find(condition01):
print(item)
for item in find(condition02):
print(item)
for item in find(condition03):
print(item)
练习1:
list01 = [ 43,4,5,5,6,7,87]
需求1:在列表中查找所有偶数。
需求2:在列表中查找所有大于10的数。
需求3:在列表中查找所有范围在10–50之间的数。
1.使用生成器函数实现以上3个需求。
2.体会函数式编程的“封装“。
将三个函数变化点提取到另外三个函数中,将共性提取到另外一个函数中。
3.体会函数式编程的"继承"与“多态"。
使用变量隔离变化点,在共性函数中调用变量。
4.测试(执行上述功能)。
list01 = [43,4,5,5,6,7,87]
# def find01():
# for item in list01:
# if item % 2 == 0:
# yield item
#
# for item in find01():
# print(item)
#
# def find02():
# for item in list01:
# if item > 10:
# yield item
#
# for item in find02():
# print(item)
#
# def find03():
# for item in list01:
# if 10 < item < 50 :
# yield item
#
# for item in find03():
# print(item)
def condition01(item):
return item % 2 == 0
def condition02(item):
return item > 10
def condition03(item):
return 10 < item < 50
def find(func_condition):
for item in list01:
if func_condition(item) :
yield item
for item in find(condition01):
print(item)
for item in find(condition02):
print(item)
for item in find(condition03):
print(item)
#方法参数,如果传递10/“张无忌"/True,叫做传递数据。
#方法参数,如果函数1/函数2/函数3,叫做传递逻辑。
练习2:
在list_helper.py 中,定义通用的查找满足条件的单个对象。
案例:
查找名称是“葵花宝典"的技能。
查找编号是101的技能。
查找持续时间大于0的技能.
建议:
1.先将所有功能实现
2.封装变化(将变化点单独定义为函数)
定义不变的函数
3.将不变的函数转移到list_helper.py 中。
4.在当前模块测试。
list_helper.py
"""
列表助手模块
"""
class ListHelper:
"""
列表助手类
"""
@staticmethod
def find_all(list_target,func_condition):
"""
通用的查找多个元素方法
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:需要查找的元素,生成器类型
"""
for item in list_target:
if func_condition(item):
yield item
@staticmethod
def find_single(list_target,func_condition):
"""
通用的查找单个元素方法
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:需要查找的元素
"""
for item in list_target:
if func_condition(item):
return item
exercise01.py
"""
测试01
"""
from common.list_helper import *
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
"""
技能信息
:param id:技能编号
:param name:技能名称
:param atk_ratio: 攻击比例
:param duration: 持续时间
"""
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duraftion = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duraftion)
list_skill = [
SkillData(101, "乾坤大挪移",5, 10),
SkillData(102, "降龙十八掌", 8, 5),
SkillData(103, "葵花宝典",10,2),
]
def condition01(item):
return item.atk_ratio > 6
def condition02(item):
return 4 < item.duraftion < 11
def condition03(item):
return len(item.name)> 4 and item.duraftion <6
generate01 = ListHelper.find_all(list_skill,condition01)
for item in generate01:
print(item)
exercise02.py
"""
测试02
"""
from common.list_helper import *
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
"""
技能信息
:param id:技能编号
:param name:技能名称
:param atk_ratio: 攻击比例
:param duration: 持续时间
"""
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duraftion = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duraftion)
list_skill = [
SkillData(101, "乾坤大挪移",5, 10),
SkillData(102, "降龙十八掌", 8, 5),
SkillData(103, "葵花宝典",10,2),
]
def condition01(item):
return item.name == "葵花宝典"
def condition02(item):
return item.id == 101
def condition03(item):
return item.duraftion > 0
re= ListHelper.find_single(list_skill,condition03)
print(re)
将核心逻辑传入方法体,使该方法的适用性更广,体现了面向对象的开闭原则。
定义:是一种匿名方法。
作用:作为参数传递时语法简洁,优雅,代码可读性强。随时创建和销毁,减少程序耦合度。
说明:形参没有可以不填,方法体只能有一条语句,且不支持赋值语句。
"""
lambda 匿名函数
语法: lambda 参数列表:函数体
注意:函数体自带return
"""
from common.list_helper import *
list01 = [43,4,5,5,6,7,87]
# def condition01(item):
# return item % 2 == 0
#
# def condition02(item):
# return item > 10
#
# def condition03(item):
# return 10 < item < 50
#
# for item in ListHelper.find_all(list01,condition02):
# print(item)
for item in ListHelper.find_all(list01,lambda item:item % 2 == 0):
print(item)
#-----------------------------------------
#无参数函数 --> lambda
def fun01():
return 100
#等价于
a = lambda :100
print(a())
#多参数函数 --> lambda
def fun02(p1,p2):
return p1> p2
b = lambda p1,p2:p1>p2
print(b(1,2))
#无返回值函数 --> lambda
def fun03(p1):
print("参数是:" ,p1)
c = lambda p1:print("参数是:" ,p1)
c(10)
#方法体只能有一条语句﹐且不支持赋值语句
def fun04(p1):
p1 = 2
# d = lambda p1:p1=2
使用def定义的函数,改为用lambda定义。
"""
测试03
"""
from common.list_helper import *
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
"""
技能信息
:param id:技能编号
:param name:技能名称
:param atk_ratio: 攻击比例
:param duration: 持续时间
"""
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duraftion = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duraftion)
list_skill = [
SkillData(101, "乾坤大挪移",5, 10),
SkillData(102, "降龙十八掌", 8, 5),
SkillData(103, "葵花宝典",10,2),
]
generate01 = ListHelper.find_all(list_skill,lambda item : item.atk_ratio > 6)
for item in generate01:
print(item)
generate01 = ListHelper.find_all(list_skill,lambda item : 4 < item.duraftion < 11)
print("------------------------------")
for item in generate01:
print(item)
generate01 = ListHelper.find_all(list_skill,lambda item : len(item.name)> 4 and item.duraftion <6)
print("------------------------------")
for item in generate01:
print(item)
练习2:定义敌人类(姓名,攻击力,防御力,血量),创建敌人列表,使用list_helper实现下列功能。
(1)查找姓名是"灭霸"的敌人。
(2)查找攻击力大于10的所有敌人。
(3)查找活的敌人数量。
在list_helper中增加判断是否存在某个对象的方法,返回值:true/false
案例1:判断敌人列表中是否存在"成昆"。
案例2:判断敌人列表中是否攻击力小于5或者防御力小于10的敌人。
步骤:
实现每个需求/单独封装变化/定义不变的函数(“继承”/“多态”)
将不变的函数提取到list_helper.py中。
体会∶函数式编程的思想(“封装﹐继承﹐多态")
在list_helper. py中增加通用的求和方法。
案例1:计算敌人列表中所有敌人的总血量。
案例2:计算敌人列表中所有敌人的总攻击力。
案例3:计算敌人列表中所有敌人的总防御力。
步骤∶实现具体功能/提取变化/提取不变/组合。
在list_helper. py中增加通用的筛选方法。
案例1:获取敌人列表中所有敌人的名称。
案例2:获取敌人列表中所有敌人的攻击力。
案例3:获取敌人列表中所有敌人的名称和血量。
在list_helper.py中增加通用的获取最大值方法。
案例1:获取敌人列表中攻击力最大的敌人。
案例2:获取敌人列表中防御力最大的敌人。
案例3:获取敌人列表中血量最高的敌人。
在list_helper.py中增加通用的升序排列方法。
案例1:将敌人列表按照攻击力进行升序排列。
案例2:将敌人列表按照防御力进行升序排列。
案例3:将敌人列表按照血量进行升序排列。
list_helper.py
"""
列表助手模块
"""
class ListHelper:
"""
列表助手类
"""
@staticmethod
def find_all(list_target,func_condition):
"""
通用的查找多个元素方法
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:需要查找的元素,生成器类型
"""
for item in list_target:
if func_condition(item):
yield item
@staticmethod
def find_single(list_target,func_condition):
"""
通用的查找单个元素方法
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:需要查找的元素
"""
for item in list_target:
if func_condition(item):
return item
@staticmethod
def get_value_number(list_target,func_condition):
"""
通用的获取元素的数量
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:数量
"""
value_number = 0
for item in list_target:
if func_condition(item):
value_number += 1
return value_number
@staticmethod
def is_exist(list_target,func_condition):
"""
通用的判断是否存在某个对象
:param list_target:需要查找的列表
:param func_condition:需要查找的条件,函数类型
函数名(参数)--》bool
:return:true/false,true表示存在,false不存在
"""
for item in list_target:
if func_condition(item):
return True
return False
@staticmethod
def get_total_sum(list_target,func_condition):
"""
通用的求和方法.
:param list_target:需要求和的列表
:param func_condition:需要求和的处理逻辑,函数类型
函数名(参数)--》int/float
:return:总和
"""
sum = 0
for item in list_target:
sum += func_condition(item)
return sum
@staticmethod
def get_sift_value(list_target,func_condition):
"""
通用的筛选方法
:param list_target:需要筛选的列表
:param func_condition:需要筛选的处理逻辑,函数类型
函数名(参数)--》int/元组/str/其它类型的对象
:return:生成器
"""
# list= []
# for item in list_target:
# list.append(func_condition(item))
# return list
for item in list_target:
yield func_condition(item)
@staticmethod
def get_max_value(list_target,func_condition):
"""
通用的获取最大值方法
:param list_target:需要搜索的列表
:param func_condition:需要筛选的处理逻辑,函数类型
函数名(参数)--》int/str
:return:最大元素对象
"""
# max_value = 0
# for item in list_target:
# if max_value < func_condition(item):
# max_value = func_condition(item)
# return max_value
max_value = list_target[0]
for i in range(1,len(list_target)):
if func_condition(max_value) < func_condition(list_target[i]):
max_value = list_target[i]
return max_value
@staticmethod
def get_incrasing_soft(list_target,func_condition):
"""
通用的升序排列方法
:param list_target:需要排序的列表
:param func_condition:需要排序的处理逻辑,函数类型
函数名(参数)--》int/float,需要比较的数据
"""
#取出前几个数据
for r in range(len(list_target)-1):
#与后面进行对比
for c in range(r+1,len(list_target)):
if func_condition(list_target[r]) > func_condition(list_target[c]):
list_target[r],list_target[c] = list_target[c],list_target[r]
exercise04.py
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
def __str__(self):
return "敌人的信息是:%s,%d,%d,%d"%(self.name,self.atk,self.defence,self.hp)
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,4,10),
Enemy("成昆",2,3,0)
]
re = ListHelper.find_single(list_enemy,lambda item:item.name == "成昆")
print(re)
generator = ListHelper.find_all(list_enemy,lambda item:item.atk > 10)
# for item in generator:
# print(item)
#生成器-->惰性操作
#优势∶节省内存
#缺点∶获取结果不灵活(不能使用索引╱切片访问结果)
#解决∶惰性操作-->立即操作
list_result = list(generator)
print(list_result)
for item in list_result[:1]:
print(item)
re= ListHelper.get_value_number(list_enemy,lambda item:item.hp > 0)
print(re)
re= ListHelper.is_exist(list_enemy,lambda item:item.name == "成昆")
print(re)
re= ListHelper.is_exist(list_enemy,lambda item:item.atk < 5 or item.defence < 10)
print(re)
exercise05.py
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,4,10),
Enemy("成昆",2,3,0)
]
re = ListHelper.get_total_sum(list_enemy,lambda item:item.hp)
print(re)
re = ListHelper.get_total_sum(list_enemy,lambda item:item.atk)
print(re)
re = ListHelper.get_total_sum(list_enemy,lambda item:item.defence)
print(re)
exercise06.py
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,4,10),
Enemy("成昆",2,3,0)
]
for item in ListHelper.get_sift_value(list_enemy,lambda item:item.name):
print(item)
for item in ListHelper.get_sift_value(list_enemy,lambda item:item.atk):
print(item)
for item in ListHelper.get_sift_value(list_enemy,lambda item:(item.name,item.hp)):
print(item)
exercise07.py
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
def __str__(self):
return "敌人的信息是:%s,%d,%d,%d"%(self.name,self.atk,self.defence,self.hp)
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,4,10),
Enemy("成昆",2,3,0)
]
re = ListHelper.get_max_value(list_enemy,lambda item:item.atk)
print(re)
re = ListHelper.get_max_value(list_enemy,lambda item:item.defence)
print(re)
re = ListHelper.get_max_value(list_enemy,lambda item:item.hp)
print(re)
exercise08.py
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
def __str__(self):
return "敌人的信息是:%s,%d,%d,%d"%(self.name,self.atk,self.defence,self.hp)
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,1,10),
Enemy("成昆",2,3,0)
]
ListHelper.get_incrasing_soft(list_enemy,lambda item:item.atk)
for item in list_enemy:
print(item)
print("-------------------------------")
ListHelper.get_incrasing_soft(list_enemy,lambda item:item.defence)
for item in list_enemy:
print(item)
print("-------------------------------")
ListHelper.get_incrasing_soft(list_enemy,lambda item:item.hp)
for item in list_enemy:
print(item)
map(函数,可迭代对象)
filter(函数,可迭代对象)
sorted(可迭代对象,key =函数, reverse = bool值)
max(可迭代对象,key =函数)
min(可迭代对象,key =函数)
"""
内置高阶函数
"""
from common.list_helper import *
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
def __str__(self):
return "敌人的信息是:%s,%d,%d,%d"%(self.name,self.atk,self.defence,self.hp)
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,1,10),
Enemy("成昆",2,3,0)
]
#1.filter:根据条件筛选可迭代对象中的元素﹐返回值为新可迭代对象。
#需求:获取所有活人
for item in ListHelper.find_all(list_enemy,lambda item:item.hp > 0):
print(item)
#等价于
re = filter(lambda item:item.hp > 0 ,list_enemy)
for item in re:
print(item)
#2.map:通用的筛选方法
#需求:获取所有敌人的名字
for item in ListHelper.get_sift_value(list_enemy,lambda item:item.name):
print(item)
#等价于
re = map(lambda item:item.name ,list_enemy)
for item in re:
print(item)
#3.max:获取最大值
#需求:获取血量最大的敌人
print(ListHelper.get_max_value(list_enemy,lambda item:item.hp))
print(max(list_enemy,key =lambda item:item.hp ))
#4.min:获取最小值
#略
#5.sort
# 内部直接修改列表,使用时无需通过返回值获取数据
# ListHelper.get_incrasing_soft(list_enemy,lambda item:item.atk)
# for item in list_enemy:
# print(item)
# print()
#
# #内部返回新列表﹐使用时必须获取返回值。
# re = sorted(list_enemy,key = lambda item:item.atk )
# for item in re:
# print(item)
#支持降序排列
re = sorted(list_enemy,key = lambda item:item.atk,reverse=True )
for item in re:
print(item)
1:([1,1,1],[2,2],[3,3,3,3])获取元组中长度最大的列表。
2:根据敌人列表,获取所有敌人的姓名与血量与攻击力。
3:在敌人列表中,获取攻击力大于90的所有活人。
4:根据防御力对敌人列表进行降序排列。
class Enemy:
def __init__(self,name,atk,defence,hp):
self.name = name
self.atk = atk
self.defence = defence
self.hp = hp
def __str__(self):
return "敌人的信息是:%s,%d,%d,%d"%(self.name,self.atk,self.defence,self.hp)
list_enemy = [
Enemy("张三",100,300,100),
Enemy("李四",50,1,10),
Enemy("成昆",2,3,0)
]
tuple01 = ([1,1,1],[2,2],[3,3,3,3])
print(max(tuple01,key = lambda item:len(item)))
print(min(tuple01,key = lambda item:len(item)))
for item in map(lambda item:(item.name,item.hp,item.atk),list_enemy):
print(item)
for item in filter(lambda item:item.atk > 90 and item.hp > 0,list_enemy):
print(item)
for item in sorted(list_enemy,key = (lambda item:item.atk > 90 and item.hp > 0),reverse=True):
print(item)
"""
外部嵌套作用域
"""
def fun01():
# 是fun01函数的局部作用域
# 也是fun02函数的外部嵌套作用域
a = 1
def fun02():
b = 2
# 可以访问外部嵌套作用域变量
# print(a)#1
# 不能修改外部嵌套作用城变量
# a = 2#创建了fun02的局部变量
# print(a)#2
nonlocal a#声明外部嵌套作用域
a = 2
fun02()
print(a)#第一次1,第二次2
fun01()
面向对象编程∶考虑问题从对象的角度出发。
函数式编程∶考虑问题从函数的角度出发。
“ 封装”:封装变化点。
“继承":抽象/隔离变化。
“多态":调用抽象的函数变量,执行具体的个性函数。
lambda:匿名方法,作为实参
def 功能1():
共性代码
个性1代码
def 功能2()∶
共性代码
个性2代码
def 功能3():
共性代码
个性3代码
"封装"
def 个性1():
个性1代码
def 个性2():
个性2代码
def 个性3():
个性3代码
"继承"
#函数类型变量就是具体共性函数的抽象
def 共性(函数类型变量):
共性代码
#多态
函数类型变量() --> 执行具体个性代码
"执行"
共性(个性1)
项目中的使用:
将共性代码提取到单独的模块中
在某个代码中导入模块
from common.list_helper import *
定义个性代码
def 个性代码():
...
调用静态方法(共性代码)
结果 = ListHelper.静态方法(要操作的数据,个性代码)
def 方法名(参数):
函数体
结果 = ListHelper.静态方法(要操作的数据,lambda 参数:函数体)
生成器-->惰性操作
优势∶节省内存
缺点∶获取结果不灵活(不能使用索引切片访问结果)
解决∶惰性操作-->立即操作