【python】18_函数之匿名函数&sorted排序

【摘要】上一篇文章简析了函数的概念、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)
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值