文章目录
【总结】匿名函数、作用域与高阶函数(2022.4.25)
1.匿名函数
语法:函数名 = lambda 形参列表:返回值(相当于普通函数的return返回值)
注意:匿名函数的本质还是函数;
普通函数中绝大部分内容,匿名函数都支持
# 举个栗子
x = lambda num1, num2: num1 + num2 #不支持定义参数类型
# 调用
print(x(10, 20))
# 练习:求个位数最大的元素
nums = [12, 39, 18, 80, 34]
##普通函数传参
def func1(x):
return x %10
print(max(nums, key=func1))
##匿名函数传参
print(max(nums, key=lambda x: x%10)) # x 代表序列中的元素
# 练习:求绝对值最大的元素
nums = [12, 39, -18, -80, 34]
print(max(nums, key=lambda x: abs(x))) # # x 代表序列中的元素
print(max(nums, key=lambda x: x**2)) # # x 代表序列中的元素
print(max(nums, key=lambda x: -x if x<0 else x)) # # x 代表序列中的元素
2. 变量作用域
2.1 变量作用域 (变量使用范围)
根据变量作用域不同,可以将变量分为两种:全局变量、局部变量
2.2 全局变量
定义在函数或者类外面的变量就是全局变量(没有定义在函数里面和类里面的变量就是全局变量)
全局变量的作用域:从定义开始到程序结束
list1 = []
for b in list1:
c = 20
print('变量:',b)
#此处 b 和 c 都是全局变量
2.3 局部变量
定义在函数里面的变量就是局部变量。(形参也是局部变量)
局部变量的作用域:从定义开始到函数结束
def func1(d, e):
f = 100
print('函数里面:',d, e, f)
#此处 d、e、f 都是局部变量
2.4 global 关键字
变量能不能使用,看的是使用的时候内存中有没有。
定义全局变量的时候,全局变量保存在全局栈区间,程序结束后才会被自动释放;
局部变量是保存在函数对应的临时栈区间中的,函数调用结束就会被自动释放。
global是函数体中的关键字,可以在函数体中修饰变量,让变量在使用和保存的时候都在全局栈区间中进行。
A. 函数中修改全局变量的值
B. 直接在函数中定义全局变量
aa = 100
bb = 100
def func2():
# 不会修改全局变量aa的值,而是创建一个全局变量aa
aa = 200
print('里面aa',aa) # 在函数里面使用的是局部变量aa的值
# print(bb) - 报错!global修饰变量必须放在变量使用之前
global bb
bb = 200
print('里面bb',bb)
global cc #加后cc变成全局变量
cc = 300
func2()
print('外面aa:',aa) # 在函数外面使用的是全局变量aa的值
print('外面bb:',bb)
3.高阶函数
3.1 函数就是变量
Python中定义函数其实就是在定义一个类型是function的变量,函数名就是变量名。
变量能做的事情函数都可以做
3.2 高阶函数 - 实参高阶函数、返回值高阶函数
A. 实参高阶函数 - 函数的参数是函数
# 定义一个函数
def func1(x):
return x
# 定义一个函数作为函数的参数
def temp():
return 100
#将temp函数作为func1的参数
print(func1(temp)) #<function temp at 0x000001F0E6A2A4C0>
B. 返回值高阶函数 - 函数的返回值是函数
def func2():
def temp(x):
return x
return temp
print(func2()(9) + 20)
3.3 常用的实参高阶函数(重要)
A. max、min、sorted、sort - 参数key要求是一个函数
max(序列, key=函数) - 按照函数制定的比较规则来获取序列中最大的元素
函数的要求:1)参数 - 有且只有一个参数;这个参数代表前面序列中的每个元素
2)返回值 - 有一个返回值;返回值就是比较对象
注意:如果一个函数的参数是函数,这个参数有两种传值方式;
a. 普通函数的函数名
b.匿名函数
nums = [10, 29, 87, 34, -231, 72]
# 练习1:求元素最大值
print(max(nums)) #87
# 练习2:求元素最大值
result = max(nums, key=lambda item:item)
print(result) #87
# 练习3:求元素个位数最大值
result = max(nums, key=lambda item:item%10)
print(result) #29
# 练习4:求元素绝对值最小值
result = min(nums, key=lambda item:item ** 2)
print(result) #10
# 练习5:求nums中数值最大的元素
nums = ['235','-290','71','1998','80']
result = max(nums, key=lambda item:eval(item) ) - 方法1
result = max(nums, key=lambda item:int(item) ) - 方法2
print(result)
# 练习6:将nums中的元素按照十位数的大小从小到大排序
nums = [913, 281, 1765, 92, 802]
result = sorted(nums, key=lambda item:item// 10 % 10)
print(result) # [802, 913, 1765, 281, 92]
## 方法1:
def temp(item): - 写法1
s = 0
for x in str(item):
s+=int(x)
return s
def temp(item): -- 写法2
list2 = []
list1 = list(str(item))
for i in list1:
list2.append(int(i))
return sum(list2)
result = min(nums, key=lambda item:temp(item))
print(result)
## 方法2
result = min(nums, key=lambda item:eval('+'.join(str(item))))
print(result)
B. map - 变换
1)map(函数, 序列) - 按照函数制定的规则将原序列转换成新的序列列表,返回值是一个map对象,本质是序列。
函数要求:a.参数:有且只有1个参数;参数代表后面这个序列中的元素
b.返回值:有一个返回值;返回值就是新序列中的元素
2)map(函数,序列1,序列2)
函数要求:a.参数:有且只有2个参数;参数代表后面2个序列中的元素
b.返回值:有一个返回值;返回值就是新序列中的元素
3)map(函数,序列1,序列2,序列3)
函数要求:a.参数:有且只有3个参数;参数代表后面3个序列中的元素
b.返回值:有一个返回值;返回值就是新序列中的元素
4)map(函数,序列1,序列2,序列3,…)
# 获取nums中所有元素的个位数
nums = [128, 239, 87, 96, 102, 91]
result = map(lambda item: item%10, nums)
print(result) #<map object at 0x00000217D5C3AB20>
print(list(result)) #[8, 9, 7, 6, 2, 1]
#######################
str1 = 'abcde'
nums = [10,20,30,40,50]
# result = map(lambda i1, i2: i1 + str(i2), str1, nums)
result = map(lambda i1, i2: f'{i1}{i2}', str1, nums)
print(result)
print(list(result)) #['a10', 'b20', 'c30', 'd40', 'e50']
C. reduce
reduce(函数,序列,初始值) - 按照函数制定的规则将序列中所有的元素合并成一个数据
函数的要求:1)参数:有且只有两个参数,第一个参数指向初始值,第二个参数代表序列中的每个元素
2)返回值:有一个返回值;描述初始值和元素之间的合并方式
from functools import reduce
nums = [10,20,30] #所有元素的和:60
result = reduce(lambda i,item: i+item, nums, 0)
print(result)
nums = [12,44,21] #所有元素个位数的和:7
result = reduce(lambda i,item: i+(item%10), nums, 0)
print(result)
nums = [10,40,20] #所有元素的乘积:8000
result = reduce(lambda i,item: i*item, nums, 1)
print(result)
nums = [10,40,20] #'104020'
result = reduce(lambda i,item: i+str(item), nums, '')
print(result)
# 练习
list1 = [10, 'abc', '2.4', 'hans', 5.5, 3] #18.5
# 方法1
result = reduce(lambda i,item: i + item,[x for x in list1 if type(x) in (int,float)], 0)
print(result)
# 方法2
result = reduce(lambda i,item: i+(item if type(item)in (int,float) else 0), list1, 0)
print(result)
# 将所有偶数的十位数和奇数的个位数求和
nums = [23, 44, 801, 132,92] #3+5+1+3+9
# A =[item%10 if item%2 != 0 else item%100//10 for item in nums]
# print(A)
result = reduce(lambda i,item: i + (item%10 if item%2 != 0 else item%100//10), nums, 1)
print(result)
D. filter(函数,序列):过滤器 - 按照函数指定的规则对序列中的元素进行筛选(过滤)
nums = [11,23,40,55]
#列表解析式方法
new_nums = [x for x in nums if x%2]
print(new_nums)
###filter
new_nums = list(filter(lambda x: x%2,nums))
print(new_nums)
# 素数(质数)判断方式
def is_prime_number(item):
for x in range(2, int(item**0.5 + 1)):
if item % x == 0:
return False
return True
new_nums = list(filter(is_prime_number,nums))
print(new_nums)
###filter
new_nums = list(filter(lambda x: x%2,nums))
print(new_nums)
# 素数(质数)判断方式
def is_prime_number(item):
for x in range(2, int(item**0.5 + 1)):
if item % x == 0:
return False
return True
new_nums = list(filter(is_prime_number,nums))
print(new_nums)