P179 Python核心-4.1 课程回顾
一、Day16复习
"""
迭代
可迭代对象
迭代器
生成器
class 可迭代对象:
def __iter__():
创建迭代器对象
class 迭代器:
def __next__():
返回一个元素
如果没有元素,则抛出一个StopIteration异常.
for 变量 in 可迭代对象:
变量得到的就是__next__方法返回值
原理:
iterator = 可迭代对象.__iter__()
while True:
try:
变量 = iterator.__next__()
except:
break
启发:调用next执行一次,计算一次,返回一次.
生成器函数:
def 函数名():
...
yield 数据
...
# 调用方法不执行
生成器 = 函数名()
# for 生成器 才执行函数体
for item in 生成器:
...
优势:延迟/惰性操作
生成器源码
class 生成器:
def __iter__():
return self
def __next__():
定义着yield以前的代码
返回yield后面的数据
"""
P180 Python核心-4.2 练习解析
一、练习1:实现enumerate函数
"""
练习:定义生成器函数my_enumerate,实现下列现象.
将元素与索引合成一个元组.
list01 = [3, 4, 55, 6, 7]
for item in enumerate(list01):
# (索引,元素)
print(item)
for index, element in enumerate(list01):
print(index, element)
"""
def my_enumerate(iterable_target):
index = 0
for item in iterable_target:
yield (index, item)
index +=1
# for index in range(len(iterable_target)):
# yield (index,iterable_target[index])
list01 = [3, 4, 55, 6, 7]
for index, element in my_enumerate(list01):
print(index, element)
二、练习2:实现zip函数
"""
# 练习: 定义生成器函数my_zip,实现下列现象.
# 将多个列表的每个元素合成一个元组.
list02 = ["孙悟空","猪八戒","唐僧","沙僧"]
list03 = [101,102,103,104]
for item in zip(list02,list03):
print(item)
"""
# 练习: 定义生成器函数my_zip,实现下列现象.
# 将多个列表的每个元素合成一个元组.
list02 = ["孙悟空","猪八戒","唐僧","沙僧"]
list03 = [101,102,103,104]
def my_zip(list01,list02):
for i in range(len(list01)):
yield (list01[i],list02[i])
for item in my_zip(list02,list03):
print(item)
# (扩展)
def my_zip2(*args):
# 根据星号元组形参args第一个参数的长度生成索引len(args[0])
for i in range(len(args[0])):
list_result = []
for item in args:
list_result.append(item[i])
yield tuple(list_result)
for item in my_zip2(list02,list03):
print(item)
三、内置生成器
枚举函数enumerate
语法:
for 变量 in enumerate(可迭代对象):
语句
for 索引, 元素in enumerate(可迭代对象):
语句
作用
遍历可迭代对象时,可以将索引与元素组合为一个元组。
zip
语法:
for item in zip(可迭代对象1, 可迭代对象2….):
语句
作用
将多个可迭代对象中对应的元素组合成一个个元组,生成的元组个数由最小的可迭代对象决定。
P181 Python核心-4.3 生成器表达式
一、生成器表达式
- 定义:用推导式形式创建生成器对象。
- 语法:变量 = ( 表达式 for 变量 in 可迭代对象 [if 真值表达式] )
二、示例代码
"""
生成器表达式
练习:exercise03.py
"""
list01 = [3, "54", True, 6, "76", 1.6, False, 3.5]
# 生成器函数
def find01():
for item in list01:
if type(item) == int:
yield item + 1
re = find01()
for item in re:
print(item)
# 生成器表达式
# 此时没有计算,更没有结果
re = (item + 1 for item in list01 if type(item) == int)
# 一次循环,一次计算,一个结果
for item in re:
print(item)
# 列表推导式
# 此时已经完成所有计算,得到所有结果
re = [item + 1 for item in list01 if type(item) == int]
# 只是获取所有结果
for item in re:
print(item)
"""
# 变量 = [itme for item in 可迭代对象 if 条件] 列表推导
# 变量 = {k,v for k,v in 可迭代对象 if 条件} 字典推导
# 变量 = {item for item in 可迭代对象 if条件} 集合推导
# 变量 = (item for item in 可迭代对象 if条件) 生成器表达式
"""
P182 Python核心-4.4 练习解析
一、练习1&2
# 练习:1. 获取列表中所有字符串
# 2. 获取列表中所有小数
# 要求:分别使用生成器函数/生成器表达式/列表推导式完成.
list01 = [3, "54", True, 6, "76", 1.6, False, 3.5]
# 练习:1
def find01():
for itme in list01:
if type(itme) == str:
yield itme
re = find01()
for item in re:
print(item)
re = (itme for itme in list01 if type(itme) == str)
for item in re:
print(item)
re = [itme for itme in list01 if type(itme) == str]
for item in re:
print(item)
# 练习:2
def find02():
for itme in list01:
if type(itme) == float:
yield itme
for item in find02():
print(item)
for item in (item for item in list01 if type(item) == float):
print(item)
for item in [item for item in list01 if type(item) == float]:
print(item)
二、练习3:
"""
参照day10/exercise02.py
完成下列练习
"""
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duration = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duration)
list_skill = [
SkillData(101,"乾坤大挪移",5,10),
SkillData(102,"降龙十八掌",8,5),
SkillData(103,"葵花宝典",10,2),
]
# 练习1:获取攻击比例大于6的所有技能
# 要求:使用生成器函数/生成器表达式完成
def find01():
for item in list_skill:
if item.atk_ratio > 6:
yield item
for item in find01():
print(item)
for item in (item for item in list_skill if item.atk_ratio > 6):
print(item)
# 练习2:获取持续时间在4--11之间的所有技能
print("--------------------")
def find02():
for item in list_skill:
if 4<item.duration<11:
yield item
for item in find02():
print(item)
for item in (item for item in list_skill if 4<item.duration<11):
print(item)
# 练习3:获取技能编号是102的技能
print("--------------------")
def find03():
for item in list_skill:
if item.id == 102:
return item
re = find03()
print(re)
# 练习4:获取技能名称大于4个字并且持续时间小于6的所有技能
print("--------------------")
def find04():
for item in list_skill:
if len(item.name) > 4 and item.duration < 6:
yield item
for item in find04():
print(item)
# 不建议使用生成器表达式
# for item in (item for item in list_skill if len(item.name) > 4 and item.duration < 6):
# print(item)
P183 Python核心-4.5 函数式编程01
一、函数式编程
定义
用一系列函数解决问题。
– 函数可以赋值给变量,赋值后变量绑定函数。
– 允许将函数作为参数传入另一个函数。
– 允许函数返回一个函数。
示例代码
"""
函数式编程 语法
"""
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)
二、函数式编程思想
"""
函数式编程 思想
练习:exercise05.py
"""
class SkillData:
def __init__(self,id,name,atk_ratio,duration):
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duration = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d"%(self.id,self.name,self.atk_ratio,self.duration)
list_skill = [
SkillData(101,"乾坤大挪移",5,10),
SkillData(102,"降龙十八掌",8,5),
SkillData(103,"葵花宝典",10,2),
]
# 需求1:获取攻击比例大于6的所有技能
def find01():
for item in list_skill:
if item.atk_ratio > 6:
yield item
# 需求2:获取持续时间在4--11之间的所有技能
def find02():
for item in list_skill:
if 4<item.duration<11:
yield item
# 需求3:获取技能名称大于4个字并且持续时间小于6的所有技能
def find04():
for item in list_skill:
if len(item.name) > 4 and item.duration < 6:
yield item
# "封装"(分而治之 变则疏之)
# 将每个变化的条件,单独定义在函数中.
def condition01(item):
return item.atk_ratio > 6
def condition02(item):
return 4<item.duration<11
def condition03(item):
return len(item.name) > 4 and item.duration < 6
# "继承"(隔离变化)
def find(func_condition):
"""
通用的查找方法
:param func_condition: 查找条件,函数类型.
函数名(变量) --> 返回值bool类型
:return:
"""
for item in list_skill:
# "多态":调用父(变量),执行子(具体函数).
# 不同子类重写父类方法,执行逻辑不同.
# if item.atk_ratio > 6:
# if condition01(item):
if func_condition(item):
yield item
for item in find(condition01):
print(item)
for item in find(condition02):
print(item)
P184 Python核心-4.6 练习解析
一、练习
"""
"""
# 1. 使用生成器函数实现以上3个需求
# 2. 体会函数式编程的"封装"
# 将三个函数变化点提取到另外三个函数中.
# 将共性提取到另外一个函数中
# 3. 体会函数式编程的"继承"与"多态"
# 使用变量隔离变化点,在共性函数中调用变量.
# 4. 测试(执行上述功能)
list01 = [43, 4, 5, 5, 6, 7, 87]
# 需求1:在列表中查找所有偶数
def find01():
for item in list01:
if item % 2 == 0:
yield item
# 需求2:在列表中查找所有大于10的数
def find02():
for item in list01:
if item > 10:
yield item
# 需求3:在列表中查找所有范围在10--50之间的数
def find03():
for item in list01:
if 10 < item < 50:
yield 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(condition02):
print(item)
# 方法参数,如果传递10/"张无忌"/True,叫做传递数据
# 方法参数,如果函数1/函数2/函数3,叫做传递逻辑
P185 Python核心-4.7 函数式编程02
一、练习
新建common包并内部建立通用模块list_helper模块,创建ListHelper类用于存储静态方法,方法为 函数调用函数
"""
列表助手模块
"""
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
另一模块导入并调用函数
"""
测试 通用模块list_helper
"""
from common.list_helper import *
class SkillData:
def __init__(self, id, name, atk_ratio, duration):
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duration = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d" % (self.id, self.name, self.atk_ratio, self.duration)
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.duration < 11
def condition03(item):
return len(item.name) > 4 and item.duration < 6
generate01 = ListHelper.find_all(list_skill, condition01)
for item in generate01:
print(item)
# 练习:在list_helper.py中,定义通用的查找满足条件的单个对象.
# 案例:查找名称是"葵花宝典"的技能.
# 查找编号是101的技能.
# 查找持续时间大于0的技能.
# 建议:
# 1. 现将所有功能实现
# 2. 封装变化(将变化点单独定义为函数)
# 定义不变的函数
# 3. 将不变的函数转移到list_helper.py中
# 4. 在当前模块测试
"""
def find01():
for item in list_skill:
if item.name =="葵花宝典":
return item
def find02():
for item in list_skill:
if item.id ==101:
return item
def find03():
for item in list_skill:
if item.duration > 0:
return item
"""
def condition04(item):
return item.name == "葵花宝典"
def condition05(item):
return item.id == 101
def condition06(item):
return item.duration > 0
"""
def find(func_condition):
for item in list_skill:
# if item.duration > 0:
# if condition06(item):
if func_condition(item):
return item
print("-------")
re = find(condition04)
print(re)
"""
re = ListHelper.find_single(list_skill, condition05)
print(re)
P186 Python核心-4.8 lambda表达式
一、lambda表达式
- 定义:是一种匿名方法。
- 作用:作为参数传递时语法简洁,优雅,代码可读性强。
随时创建和销毁,减少程序耦合度。 - 语法
– 定义:
变量 = lambda 形参: 方法体
– 调用:
变量(实参) - 说明:
– 形参没有可以不填
– 方法体只能有一条语句,且不支持赋值语句。
二、示例代码
"""
lambda 匿名函数
语法:lambda 参数列表:函数体
注意:函数体自带return
练习1:将exercise06.py中,使用def定义的函数,
改为使用lambda.
"""
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
re = a()
print(re)
# 多参数函数 --> lambda
def fun02(p1, p2):
return p1 > p2
b = lambda p1, p2: p1 > p2
re = b(1, 2)
print(re)
# 无返回值函数 --> lambda
def fun03(p1):
print("参数是:", p1)
c = lambda p1: print("参数是:", p1)
c(100)
# 方法体只能有一条语句,且不支持赋值语句
def fun04(p1):
p1 = 2
# d = lambda p1:p1 = 2
P187 Python核心-4.9 lambda练习
一、练习
from common.list_helper import *
class SkillData:
def __init__(self, id, name, atk_ratio, duration):
self.id = id
self.name = name
self.atk_ratio = atk_ratio
self.duration = duration
def __str__(self):
return "技能数据是:%d,%s,%d,%d" % (self.id, self.name, self.atk_ratio, self.duration)
list_skill = [
SkillData(101, "乾坤大挪移", 5, 10),
SkillData(102, "降龙十八掌", 8, 5),
SkillData(103, "葵花宝典", 10, 2),
]
# 使用lambda实现
# 案例:查找名称是"葵花宝典"的技能.
# 查找编号是101的技能.
# 查找持续时间大于0的技能.
re = ListHelper. \
find_single(list_skill,
lambda item: item.name == "葵花宝典")
print(re)
re = ListHelper.find_single(list_skill, lambda element: item.id == 101)
print(re)
re = ListHelper.find_single(list_skill, lambda element: item.duration > 0)
print(re)
P188 Python核心-4.10 练习解析及作业
一、练习1
在通用模块list_helper模块,ListHelper类中新增静态方法如下
@staticmethod
def get_count(list_target, func_duration):
"""
通用的计算满足某个条件的元素数量方法
:param list_target: 需要查找的列表
:param func_condition: 需要查找的条件,函数类型
函数名(参数) --> bool
:return: 满足条件元素的数量
"""
count_value = 0
for item in list_target:
if func_duration(item):
count_value += 1
return count_value
实现lambda
# 需求1:计算技能列表中技能名称大于4个字的技能数量.
# 需求2:计算技能列表中技能持续时间小于等于5的技能数量.
# 步骤:
# 实现每个需求/单独封装变化/定义不变的函数("继承"/"多态")
# 将不变的函数提取到list_helper.py中
"""
def get_count01():
count_value = 0
for item in list_skill:
if len(item.name) > 4:
count_value +=1
return count_value
def get_count02():
count_value = 0
for item in list_skill:
if item.duration <= 5:
count_value +=1
return count_value
def get_count(func_duration):
count_value = 0
for item in list_skill:
# if item.duration <= 5:
if func_duration(item):
count_value +=1
return count_value
"""
re = ListHelper.get_count(list_skill,lambda item:len(item.name) > 4)
print(re)
re = ListHelper.get_count(list_skill,lambda item:item.duration <= 5)
print(re)