第八章 函数-3
8.3 lambda函数
如果一个函数的函数体仅有 1 行表达式,则该函数就可以用 lambda 表达式来代替。lambda 表达式,又称匿名函数,常用来表示内部仅包含 1 行表达式的函数。lambda 表达式的语法格式如下:
name = lambda [list] : 表达式
其中,定义 lambda 表达式,必须使用 lambda 关键字;[list] 作为可选参数,等同于定义函数是指定的参数列表;name为该表达式的名称。该语法格式转换成普通函数的形式,如下所示:
def name(list):
return 表达式
name(list)
使用普通方法定义此函数,需要 3 行代码,而使用 lambda 表达式更简洁,可读性好。看个例子:
squareSum = lambda x,y:x*x+y*y
print(squareSum(1,2))
如果使用函数方式实现,如下:
def squareSum(x,y):
return x*x+y*y
print(squareSum(1,2))
lambda函数用法(这部分难度大,可以不看):
1. 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。例子就是我们上面给出的,当然我们还可以再提供一个例子如下:
passtest = lambda score: 1 if score >60 else 0 #成绩是否及格
print(passtest(46)) #0
print(passtest(86)) #1
2. 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。
import time
# 为了把标准库time中的函数sleep的功能屏蔽(Mock),我们可以在程序初始化时调用:
time.sleep=lambda x: None
# 这样,在后续代码中调用time库的sleep函数将不会执行原有的功能。例如:
time.sleep(3) # 程序不会休眠 3 秒钟,而是因为lambda输出为None,所以这里结果是什么都不做
3. 将lambda函数作为参数传递给其他函数。典型的用法就是下面我们常见的几种高阶函数。
①sorted函数
my_list = [3,5,-4,-1,0,2,-6]
#按照绝对值、降序排序
new_list=sorted(my_list, key=lambda x: abs(x),reverse=True)
print(my_list) # [3,5,-4,-1,0,2,-6]
print(new_list) # [-6, 5, -4, 3, 2, -1, 0]
补充sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
②filter函数
filter()方法用于根据一定的条件对给定的列表进行过滤。使用示例如下:
my_list = [1,2,3,4,5,6,7,8,9,10]
new_list = list(filter(lambda a: (a % 3 == 0),my_list))
print(new_list) # [3, 6, 9]
my_list是一个列表,它作为参数传递给filter函数。filter函数使用lambda函数检查列表中的值是否满足整除3的条件,输出列表中满足条件的值。
或者也可以按照下面方法实现:
def is3times(n):
return n % 3 == 0
newlist = filter(is3times, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(list(newlist)) # [3, 6, 9]
③map函数
map函数可以根据提供的函数对指定序列做映射,乘风破浪的例子来了:
# ===========一般写法:===========
# 1、计算平方数
def square(x):
return x ** 2
m=map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
print(list(m)) # 结果:[1, 4, 9, 16, 25]
# ===========匿名函数写法:============
# 2、计算平方数,lambda 写法
m=map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(list(m)) # 结果:[1, 4, 9, 16, 25]
# 3、提供两个列表,将其相同索引位置的列表元素进行相加
m=map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
print(list(m)) # 结果:[3, 7, 11, 15, 19]
综上所述,Python中的map()函数是一个将给定的列表的值依次在所定义的函数关系中迭代并返回一个新列表。写出下列程序运行结果。
my_list = [1,2,3,4,5,6,7,8,9]
new_list = list(map(lambda a:(a % 3!= 0),my_list))
print(new_list) #[True, True, False, True, True, False, True, True, False]
④reduce函数
reduce函数将一个数据集合(列表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。参考一个例子:
from functools import reduce
# ===========一般写法:===========
# 1、两数相加
def add(x, y):
return x + y
r=reduce(add, [1, 3, 5, 7, 9]) # 计算列表元素和:1+3+5+7+9
print(r) # 结果:25
"""
===========执行步骤解析:===========
调用 reduce(add, [1, 3, 5, 7, 9])时,reduce函数将做如下计算:
1 先计算头两个元素:f(1, 3),结果为4;
2 再把结果和第3个元素计算:f(4, 5),结果为9;
3 再把结果和第4个元素计算:f(9, 7),结果为16;
4 再把结果和第5个元素计算:f(16, 9),结果为25;
5 由于没有更多的元素了,计算结束,返回结果25。
"""
# ===========匿名函数写法:===========
# 2、两数相加,lambda 写法
r=reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(r) # 结果:15
# 当然求和运算可以直接用Python内建函数sum(),没必要动用reduce。
# 3、但是如果要把序列 [1, 3, 5, 7, 9] 变换成整数 13579,reduce就可以派上用场:
def fn(x, y):
return x * 10 + y
r=reduce(fn, [1, 3, 5, 7, 9])
print(r) # 结果:13579
编程练习:
1. 使用不同方法求1+2+3+……+100的和
# 方法1
# 这个方法如果不能想出来,自己惩罚自己
# doing sit-ups and jumping jacks,100个怎么样?
# 仰卧起坐和开合跳,又学了新单词了啊!
s=0
for i in range(1,101):
s=s+i
print(s)
# 方法2 使用了reduce函数
from functools import reduce
def add(x,y):
return x + y
print (reduce(add, range(1, 101)))
# 方法3,就一行代码呦!
print(sum(range(1,101)))
4. 函数式编程
下面这个例子比较难于理解,别急,慢慢来。
# 定义一个普通的python函数并嵌入 Lambda,函数接收传入的一个参数 x。
# 然后将此参数添加到lambda函数提供的某个未知参数 y 中求和。
def new_func(x):
return(lambda y:x + y)
# 只要使用new_func(),就会调用new_func中存在的lambda函数。
# 每次都可以将不同的值传递给参数。
f1 = new_func(1) # x=5,返回 1+y
f2 = new_func(2) # x=2,返回 2+y
print(f1(3)) # y=3,返回 1+y=4
print(f2(4)) # y=4,返回 2+y=6