Day 12 函数使用之进阶
几点总结
-
函数式编程: 遇到问题首先想到的有没有一个函数能够解决这个问题,有直接调用,没有则创建
-
return作用,将数据作为返回值返回,提前结束函数(执行函数体的时候,遇到return函数直接结束)相当于循环中的break,return只能在函数体中使用
def func3(n): # n = 5 for x in range(1, n): if x % 3 == 0: return x print(f'x:{x}') print(func3(5)) #x : 1,x : 2,3 其中3是返回值,
-
列表中的元素转换成字符串时,产生一个一个单一的字符
-
eval()函数可用性很强
变量作用域
-
变量作用域不同,可将变量分为全局变量和局部变量
-
全局变量: 没有定义在函数或者类中的变量默认都是全局变量,从定义开始到程序结束都可以使用,函数中也可以使用全局变量
a = 100 # 全局变量 for i in range(5): print("a:", a)
-
局部变量: 定义在函数中的变量,就是局部变量,从定义开始,到函数调用结束,调用函数时,才能使用局部变量,形式参数就是局部变量,只能在函数里面用
-
函数调用的时候申请内存,存储变量,调用结束销毁内存,输出返回值,返回值存储在全局栈区间
全局变量和局部变量存储原理 全局变量默认保存在全局栈区间, 调用函数的时候系统回自动为这个函数创建一个临时栈区间,用来保存函数中产生的数据 局部变量就是保存在临时栈区间中的,函数对应的临时栈区间会在函数调用结束时自动释放
-
在函数中可以通过关键字 global 修改局部变量的保存方式,将局部变量保存在全局变量中
globalname = "笑话" def func(m): global n n = 1000 #在函数内部定义全局变量 print("函数里面m=", m) print("函数里面n=", n) global name name = "瞎画画" #在函数内部修改全局变量 func(100) n = 10 print("name:", name)
匿名函数
-
函数名 = lambda 形参列表 : 返回值
sum_2 = lambda num1=1, num2=2: num1 + num2 """ 变量 返回值 即被定义,也被使用 """ """ 匿名函数即被定义,也被使用 匿名函数的形参至少一个 匿名函数的调用和普通函数一样 匿名函数不能使用类型说明,无默认值的类型说明,在匿名函数中不能使用 主要时因为,语法格式相互矛盾 """
高阶函数
-
实参高阶函数
# 1. 实参高阶函数 # 函数的参数是函数的函数就是实参高阶函数 # 给参数是函数的参数传参:a.使用普通函数函数名;b.使用匿名函数 # 重点:掌握系统或者第三方库提供的实参高阶函数的用法 # 常见的实参高阶:max、min、sorted、列表.sort、map、reduce
-
max( )) 高阶函数
""" max(序列) 直接比较序列中元素的大小,求最大值 max(序列,key = 函数) 按照函数指定的规则比较序列中元素大小,获取最大值 函数要求: 有且只有一个参数(这个参数代表序列中的每一个元素)序列是比较的序列,唯一需要注意点,参数是序列中的每一个元素 有一个返回值(返回值就是比较对象),,,返回值代表比较对象,按照什么标准或者属性来进行排序,比较 """
# 练习1:求list1中长度最长的字符串 list1 = ['你好', 'hello', 'how are you', 'thank you! and you?', '好好学习,天天向上'] print(max(list1, key=lambda i: len(i))) # 练习2:求nums中十位数最小的元素 nums = [92, 129, 37, 99, 150, 501] print(max(nums, key=lambda i: i // 10 % 10)) # 练习3:将所有的学生按照年龄值从小到大排序 students = [ {'name': 'stu1', 'age': 18, 'score': 90}, {'name': 'stu2', 'age': 22, 'score': 98}, {'name': 'stu3', 'age': 25, 'score': 78}, {'name': 'stu4', 'age': 19, 'score': 81}, {'name': 'stu5', 'age': 20, 'score': 92} ] print(sorted(students, key=lambda i: i["age"] % 10, reverse=True)) # 练习4:求nums中各个位之和最大的元素 nums = [123, 78, 90, 201, 192, 330] # print(max(nums, key=lambda i: sum(int(j) for j in str(i)))) print(max(nums, key=lambda i: eval("+".join(str(i))))) # 用评估函数对字符串进行拼接,最后转换成可操作的表达式,去掉引号 # i = 123 # j = str(i) # print(j) # print(list(j))
-
map () 高阶用法
""" 基于原序列中的元素创建一个新的序列 通过函数描述的规则,基于原序列的元素,创建新的序列 map(函数,序列) 函数的要求: 有且只有一个参数,,代表后面序列中的每个元素 有一个返回值,返回值就是新序列中的元素 map(函数,序列,序列) 函数的要求: 有且只两个参数,,代表后面序列中的每个元素 有一个返回值,返回值就是新序列中的元素 """
# 练习1:获取names中每个人的姓 names = ['何晓东', '张三', '李四', '王五', '王二', '赵六'] family_name = map(lambda i: i[0], names) print(list(family_name)) # 练习2: i , j是序列中的直接元素 students = [ {'name': 'stu1', 'age': 18, 'score': 90}, {'name': 'stu2', 'age': 22, 'score': 98}, {'name': 'stu3', 'age': 25, 'score': 78}, {'name': 'stu4', 'age': 19, 'score': 81}, {'name': 'stu5', 'age': 20, 'score': 92} ] subjects = ['电子信息', '金融数学', '园林设计', '经济', '计算机软件'] # ['电子信息-stu1', '金融数学-stu2',....] result = map(lambda i, j: f"{j}-{i['name']}", students, subjects) print(list(result))
-
reduce() 高阶函数
""" 将序列中的元素合并成一个数据 基于原序列中所有的元素,,得到一个数据 reduce(函数,序列,初始值) - 按照函数指定的规则 函数的要求: 有且只有两个参数 第一个参数指向初始值,第二个参数代表序列中的每个元素 需要一个返回值,(返回值就是合并规则) 初始值: 累计就和 初始值是0 累计求乘积 初始值是1 字符串合并,初始值是空串 """
from functools import reduce nums = [12, 301, 40, 55, 112] # 求个位数的和 result = reduce(lambda i, j: i + eval(str(j)[-1]), nums, 0) # 用eval函数评估字符串,将其转换成数字 print(int(result)) # 123014055112 result = reduce(lambda i, j: i + eval(str(j)[-1]), nums, 0)
迭代器
-
是一个序列,无法直接创建迭代器,只能将其他序列转换成迭代器
""" 特点: 打印迭代器时,无法查看元素有哪些 无法通过len()获取迭代器中元素的个数 使用迭代器中的元素,必须将元素从迭代器中取出来.取走的元素会从迭代器中永远消失,用一个就少一个 任何数据都可以作为迭代器的元素 """
# 创建迭代器 i1 = iter("abc") i2 = iter(["abc", 1, 2, 3, 5]) print(i1) print(i2)
""" 获取单个元素 next(迭代器) 获取迭代器中最上面的元素 转换成列表也会使迭代器中的元素,消失 遍历: 也会取到迭代器中的元素,迭代器会消失 for 变量 in 迭代器: 操作 执行完,迭代器就被掏空 """
i2 = iter(["abc", 1, 2, 3, 5]) for i in i2: print(i) print(list(i2)) #[]
i2 = iter(["abc", 1, 2, 3, 5]) print(next(i2)) # abc list1 = list(i2) print(list1) # [1, 2, 3, 5] print(list(i2)) # []
作业
-
写一个匿名函数,判断指定的年是否是闰年 (先直接用普通函数)
""" 写一个匿名函数,判断指定的年是否是闰年 (先直接用普通函数) """ # # leap_year = lambda i: (i % 4 == 0 and i % 100 != 0) or i % 400 == 0 # 给匿名函数返回值时,命名时会有警告 # print(leap_year(2023)) # # def leap_year(year): # return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 # # # print(leap_year(2023)) leap_year = lambda i: (i % 4 == 0 and i % 100 != 0) or i % 400 == 0# 给匿名函数返回值时,命名时会有警告 print(leap_year(2023)) # 匿名函数变量本质上是形式参数,需要传入参数值
-
写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)
""" 写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数) """ list1 = [1, 2, 3] def exchange(list_one=[]): new_list = [] for i in range(-1, -len(list_one) - 1, -1): # 所有的排序都是从小到大 print(i) new_list.append(list_one[i]) return new_list
-
编写一个函数,计算一个整数的各位数的平方和
"""
编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 5(1的平方加上2的平方) sum1(123) -> 14
"""
num = 123
def product(num_one):
return eval("**2+".join(str(num_one)) + "**2")
print(product(num))
- 求列表 nums 中绝对值最小的元素
"""
求列表 nums 中绝对值最小的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最小值是:-23
"""
nums = [-23, 100, 89, -56, -234, 123]
result = min(nums, key=lambda i: i ** 2)
print(result)
-
已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value
""" 已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value A = ['name', 'age', 'sex'] B = ['张三', 18, '女'] 新字典: {'name': '张三', 'age': 18, 'sex': '女'} """ A = ['name', 'age', 'sex'] B = ['张三', 18, '女'] C = map(lambda i, j:(i,j), A, B) print(dict(C))
-
已经三个列表分别表示5个学生的姓名、学科和班号,使用map将这个三个列表拼成一个表示每个学生班级信息的的字典
""" 已经三个列表分别表示5个学生的姓名、学科和班号, 使用map将这个三个列表拼成一个表示每个学生班级信息的的字典 names = ['小明', '小花', '小红', '老王'] nums = ['1906', '1807', '2001', '2004'] subjects = ['python', 'h5', 'java', 'python'] 结果:{'小明': 'python1906', '小花': 'h51807', '小红': 'java2001', '老王': 'python2004'} """ names = ['小明', '小花', '小红', '老王'] nums = ['1906', '1807', '2001', '2004'] subjects = ['python', 'h5', 'java', 'python'] result = map(lambda i, j, k: (f"{i}", f"{j}{k}"), names, nums, subjects) print(dict(result))
-
已经一个列表message, 使用reduce计算列表中所有数字的和
""" 已经一个列表message, 使用reduce计算列表中所有数字的和 message = ['你好', 20, '30', 5, 6.89, 'hello'] 结果:31.89 """ message = ['你好', 20, '30', 5, 6.89, 'hello'] from functools import reduce def num(list_one = []): new_list = [] for i in list_one: if type(i) == int or type(i) == float: new_list.append(i) else: count = 0 for j in i: if "0" <= j <= "9": print(count) count +=1 else: break if count == len(i): new_list.append(eval(i)) return new_list print(num(message)) result = reduce(lambda k,item: k+item, num(message),0) print(result) # 61.89 from functools import reduce message = ['你好', 20, '30', 5, 6.89, 'hello'] result = reduce(lambda i, j: i + j if type(j) == int or type(j) == float else i, message, 0) print(result)
-
已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ]
1)获取列表中y坐标最大的点
2)获取列表中x坐标最小的点
3)获取列表中距离原点最远的点
4)将点按照点到x轴的距离大小从大到小排序
""" 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标) points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ] ```python points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ] ``` 1)获取列表中y坐标最大的点 2)获取列表中x坐标最小的点 3)获取列表中距离原点最远的点 4)将点按照点到x轴的距离大小从大到小排序 """ points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ] #1)获取列表中y坐标最大的点 print(max(points,key=lambda i :i[-1])) #2)获取列表中x坐标最小的点 print(min(points,key=lambda i :i[0])) #3)获取列表中距离原点最远的点 print(max(points,key=lambda i :i[0]**2+i[-1]**2)) #4)将点按照点到x轴的距离大小从大到小排序 print(sorted(points,key=lambda i :i[0]**2+i[-1]**2))
-
封装一个函数完成斗地主发牌的功能。
"""
封装一个函数完成斗地主发牌的功能。
"""
from random import shuffle
colors = ['♠', '♣', '♥', '♦']
numbers = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
J = 11
Q = 12
K = 13
A = 14
g = 16
l = 15
X = 10
pukes = [i + k for i in colors for k in numbers]
print(len(pukes))
pukes.extend(["big", "small"])
print(pukes)
# 实现发牌
def deal(pukes: list):
shuffle(pukes)
print(pukes)
pukes = iter(pukes)
for i in range(3):
print(i)
player = []
for j in range(17):
player.append(next(pukes))
print(f"player{i + 1}的牌是:",
sorted(player, key=lambda x: eval(x[-1]) + 10 if eval(x[-1]) == 0 else eval(x[-1])))
deal(pukes)