【摘要】上一篇文章简析了函数的概念、4个参数以及作用域。本文旨在深入理解函数,掌握匿名函数以及sorted()函数的使用。
1.lamda匿名函数
1.1 求和函数的匿名函数写法
通常情况下,如果我们要定义一个求和函数,需要以下几行代码
def sum(arg1:int, arg2:int)->int:
#形参arg1和arg2的类型都是int型,返回值也是int型
return arg1 + arg2
print("运行结果: ", sum(1, 2))
print("运行结果: ", sum(3, 5))
如果有了匿名函数,这个函数的定义会更加简单。
匿名函数,顾名思义,就是没有名字的函数。
其定义格式为:
lambda 形参:返回值
lambda函数能接收任何数量的参数但只能返回一个表达式的值
如果用匿名函数的形式来定义上面的求和函数,只需要一行
lambda_sum = lambda arg1, arg2 : arg1+arg2
这里,虽然匿名函数没有名字,但是我们可以把其赋给一个变量。
print("匿名函数".center(50, '*'))
lambda_sum = lambda arg1, arg2 : arg1+arg2
print("运行结果: ", lambda_sum(1, 2))
print("运行结果: ", lambda_sum(3, 5))
1.2 求幂方函数的匿名函数写法
def mypow(num1, num2=2):
"""
num1的num2次方
:param num1:
:param num2:
:return:
"""
return num1 ** num2
print(mypow(2))
print(mypow(2,3))
定义一个求幂方的函数,形参有两个值,num1是必选参数,num2是默认参数,默认值为2,在调用时如果不传num2的值,即求num1的平方。
如果用匿名函数的形式来定义上面的求幂方函数,代码如下:(核心代码只有第一行)
lambda_mypow = lambda num1, num2=2:num1 ** num2
print("匿名函数".center(50, '*'))
print(lambda_mypow(2))
print(lambda_mypow(2, 3))
1.3将匿名函数作为实参
如果我们想要同时实现加减乘除,按照之前的做法,就是分别定义四个函数来分别实现这四种功能。但是有了匿名函数,我们使用一个函数即可实现四种运算。
def myFunc(num1, num2, fun=pow):
print('num1=', num1, end=', ')
print('num2=', num2, end=', ')
print("result=", fun(num1, num2))
这里我们定义了一个名为myFunc的函数,共有3个形参,第三个默认参数fun通过实参传进来的值对前两个必选参数num1和num2进行运算。
myFun(2, 3, lambda x, y: x + y)
myFun(2, 3, lambda x, y: x * y)
myFun(2, 3, lambda x, y: x ** y)
第一行代码,我们给fun形参传入一个匿名函数 lambda x, y: x + y,返回值为x+y。
第二行代码,我们给fun形参传入一个匿名函数 lambda x, y: x * y,返回值为x*y。
第三行代码,我们给fun形参传入一个匿名函数 lambda x, y: x * *y,返回值为x**y。
2.排序
2.1 列表的sort()方法
我们之前学习列表时,知道列表是有序的,并且带有sort()方法,可以帮助我们排序。
那如果要对元组、集合甚至是字典排序呢?元组和集合我们可以将其转换为列表,再使用列表的sort()方法排序,字典又要怎样排序呢?
可以看到,元组没有sort()方法,无法直接排序。
只能先将其类型转换为列表类型,再对其进行排序。
2.2 sorted()内置函数
还好python有内置方法sorted()函数,帮助我们解决了这么麻烦的排序。sorted()函数可以将一切可迭代对象排序
集合是无序的,但也可以直接排序。
元组也不用再转换成列表,再进行排序了。
但这里要注意的是,sorted()方法排序之后,返回值的类型是列表类型。
其中key形参,可以通过我们的实参传值确定排序的顺序是什么,reverse的flag默认为False从小到大排序,如果需要从大到小排序,只需将其flag设置为True即可。
2.3 复杂的排序
假如我们现在有一个列表的嵌套,我们如何对其价格或者数量进行排序呢?
这里就要用到上面介绍的匿名函数以及sorted()方法了。
sort_goods = sorted(goods, key=lambda x: x[1], reverse=True)
print("按照价格进行排序".center(30, '*'))
print(sort_goods)
key值是决定sorted()方法用什么排序,reverse的值代表正序逆序。
这里解释一下:我们给key值一个匿名函数lambda x: x[1],goods传进来是一个列表,x这个形参在这个列表中代表其中一个小列表,返回值是x[1]表示给key值返回的是每个小列表的第2个字段,即商品价格。又因为reverse=True,所以是根据商品价格的从大到小排序。
如果想要根据商品的数量从小到大排序,也很简单。
sort_count_goods = sorted(goods, key=lambda x:x[2])
print("按照商品数量进行排序".center(30, '*'))
print(sort_count_goods)
key值传入的是一个匿名函数lambda x:x[2],x表示列表中嵌套的小列表,又因为我们要对价格进行排序,因此是每个小列表中的第3个字段。从小到大排序,reverse就不需要再设置了,默认值为False。
【补充】这里排序之后的显示不是很友好,python中提供了一个类似于mysql表格显示的模块,叫prettytable。我们导入这个模块,再进行显示就很友好了。
在导入模块前,需要先下载模块。
1)如果是在windows系统中,pycharm-》settings-》Project Interpreter
点击右边蓝色区域的+号。
会出现如上图所示区域。需要什么模块,我们在蓝色区域输入并搜索。
搜索成功之后,点击蓝色区域安装即可。
至此,安装成功。
2)如果是在linux系统中,直接pip install prettytable即可。
定义一个友好显示的函数pretty_show( )
def pretty_show(goods):
"""
以表格的方式友好的显示商品信息
:param goods:
:return:
"""
# 导入prettytable模块里面的类PrettyTable, 并起一个别名pt
from prettytable import PrettyTable as pt
# 实例化表格对象
table = pt()
# 往表格里面添加表头信息
table.field_names = ["Name", "Price", "Count"]
# 依次添加每一行商品的信息;
for good in goods:
table.add_row(good)
# 最终显示表格
print(table)
调用这个函数,来显示我们之前的列表和根据价格从大到小排序之后的列表
pretty_show(goods)
sort_goods = sorted(goods, key=lambda x: x[1], reverse=True)
print("按照价格进行排序".center(30, '*'))
pretty_show(sort_goods)
按照商品数量进行排序之后的友好显示
sort_count_goods = sorted(goods, key=lambda x:x[2])
print("按照商品数量进行排序".center(30, '*'))
pretty_show(sort_count_goods)
2.4 字典的排序
同样是上面的数据,但是我们选用字典这个数据结构来存储。如何实现根据商品的价格或者数量排序呢?
之前讲过,字典的items方法会返回一个键/值对列表。
print(goods.items())
我们可以通过这个方法,拿到字典的键值对列表。而商品的价格和数量分别在列表中,每个键值对的第二个字段中的第二个/第三个字段。
sorted_by_price = sorted(goods.items(), key=lambda x:x[1][1])
print("按照价格进行排序".center(30, '*'))
print(sorted_by_price)
sorted_by_count = sorted(goods.items(), key=lambda x:x[1][2])
print("按照商品数量进行排序".center(30, '*'))
print(sorted_by_count)
3.匿名函数和sorted函数综合小练习-----奇偶数排序
问题描述:
有一个整数列表(10个元素), 要求调整元素顺序,把所有的奇数放在前面,偶数放在后面。
现在假设我们有一个列表li,要如何把奇数放在前面,偶数放在后面呢?
li = [30, 10, 21, 32, 45, 56, 23, 23, 23, 56]
其实用sorted()方法实现很简单。实现思路是:key值传入一个匿名函数,该函数实现的功能为判断奇偶数,如果是奇数返回值带0,如果是偶数返回值带1。再使用sorted排序,自然0在前(即奇数在前),1在后(即偶数在后)。
代码实现如下:
li = [30, 10, 21, 32, 45, 56, 23, 23, 23, 56]
print(sorted(li, key=lambda x: 1 if x % 2 == 0 else 0))
key值接受的是匿名函数lambda x: 1 if x % 2 == 0 else 0 包含一个if三元运算符。如果x对2取余为0,表示x是个偶数,返回1;否则返回0。
也可以将判断是否为偶数的式子封装成函数
def isEven(num):
"""判断是否为偶数"""
return num % 2 == 0
li = [30, 10, 21, 32, 45, 56, 23, 23, 23, 56]
sorted_num = sorted(li, key=lambda x: 1 if isEven(x) else 0)
print(sorted_num)
类似题目还有18年携程的题
给定一个整形数组, 将数组中所有的0移动到末尾, 非0项保持不变;
在原始数组上进行移动操作, 勿创建新的数组;
• 输入: 数组的记录;0 7 0 2
• 输出: 调整后数组的内容; 7 2 0 0
li = [0, 7, 0, 2]
li.sort(key=lambda x: 1 if x == 0 else 0)
print(li)