大爽Python入门教程 6-6 函数进阶 匿名函数 与 `sort`高级排序
大爽Python入门公开课教案 点击查看教程总目录
函数赋值
函数不仅可以被调用。
函数本身也可以被赋值。
示例如下
def square(x):
return x * x
a = square
print(a(2))
输出为4
这里详细说明一下,声明函数之后。
后面再使用函数名时,
- 带括号就是调用函数,会直接执行函数。
- 不带括号只有函数名,就是将函数这个整体(功能)看作一个变量,
赋值给其他变量。
上面就是第二种,a
变量也就是square
函数。
匿名函数
在我看来,定义函数时,使用匿名函数定义,是一种缩写,或者说简写。
匿名函数,顾名思义,隐匿姓名。
是在定义时省略def
和函数名的一种写法。
语法如下
lambda arguments: expression
其中,arguments
为参数,多个参数逗号分隔。
expression
为表达式(返回该式运算结果,所以里面不用写return
语句)。
匿名函数里面只能写一个表达式。
但是这个时候有个问题,这样定义完了,没办法使用它。
因为没有人知道它的名字。
所以一般还是要把匿名函数赋值给一个变量或者之类的。
使用示例如下
a = lambda x: x * x
其等价于
def a(x):
return x * x
调用方式都是一样的,比如a(2)
再举一个例子,下面会用到
函数如下
def b(item):
return item[1]
其匿名函数写法为
b = lambda item: item[1]
其作用是返回item
的第二个元素(或者说索引为1的元素)。
sorted
探究
深入认识
本章第五节,只是初步介绍了下sorted
函数, 并简单使用了下。
现在来细看下。
官网上,sorted
详细参数形式如下
sorted(iterable, *, key=None, reverse=False)
这里展示下官网介绍,并逐句翻译
Return a new sorted list from the items in
iterable
.
对可迭代对象iterable
中的项进行排序,得到一个新的已排序列表,并返回该列表。
Has two optional arguments which must be specified as keyword arguments.
具有两个可选参数,它们都必须使用关键字参数来进行传参。
key
specifies a function of one argument that is used to extract a comparison key from each element in iterable (for example,key=str.lower
). The default value isNone
(compare the elements directly).
key
指定一个函数,该函数接受一个参数。
该函数用于从iterable
的每个元素中提取用于比较的键 (例如 key=str.lower
)。
默认值为 None
(直接比较元素)。
reverse
is a boolean value. If set toTrue
, then the list elements are sorted as if each comparison were reversed.
reverse
为一个布尔值。
如果设为 True
,则返回的列表中每个元素将按反向顺序比较进行排序。
补充: 上面的*
参数好像不能用。。。
绝对值排序
比如下面这样一个列表
lst = [-9, -4, 3, -5, -2, -7, -8, -5, 8, -4]
想要按绝对值大小排序怎么排。
获取绝对值的方法为abs(x)
使用示例如下
>>> abs(-2)
2
排序代码如下
>>> lst = [-9, -4, 3, -5, -2, -7, -8, -5, 8, -4]
>>> sorted(lst, key = lambda x: abs(x))
[-2, 3, -4, -4, -5, -5, -7, -8, 8, -9]
现在我们再来理解下上面官方文档中的话:
key
指定一个函数,该函数接受一个参数。
该函数用于从iterable
的每个元素中提取用于比较的键 (例如 key=str.lower
)。
元组指定项排序
比如下面这样一个列表,里面每一项都是一个二元组
每个元组的第一项是水果名字,第二项是一份的价格。
fruits = [
("apple", 10),
("banana", 5),
("cherry", 20),
("lemon", 15),
("orange", 8)
]
现在希望给这些水果用价格来排序,
排序代码如下
>>> sorted(fruits, key = lambda item: item[1])
[('banana', 5), ('orange', 8), ('apple', 10), ('lemon', 15), ('cherry', 20)]
字典排序
比如下面这样一个字典,键是学生名字,值是学生分数。
scores = {
"Smith": 84,
"Anderson": 91,
"Clark": 69,
"ZhangSan": 82,
"Allen": 90,
"Green": 91
}
现在希望把这些学生的成绩排序。
这个时候常用的排序方法如下
>>> sorted(scores.items(), key = lambda item: item[1])
[('Clark', 69), ('ZhangSan', 82), ('Smith', 84), ('Allen', 90), ('Anderson', 91), ('Green', 91)]
还记得dict.items()
方法吗。
它得到的是字典键值对组成的view对象。
如下
>>> scores.items()
dict_items([('Smith', 84), ('Anderson', 91), ('Clark', 69), ('ZhangSan', 82), ('Allen', 90), ('Green', 91)])
当然这个排序效果还不行,因为大多是时候都希望得到的是降序的,
这样能够快速取到前几名。
此时排序代码如下
>>> sorted(scores.items(), key = lambda item: item[1], reverse=True)
[('Anderson', 91), ('Green', 91), ('Allen', 90), ('Smith', 84), ('ZhangSan', 82), ('Clark', 69)]
那么之后想取前几名就容易了,使用切片就好。
拓展说明
sort
有一个叫sort
方法和sorted
很像。
这里说下区别,
sort
一般是list
的方法,其语法为附在list
后面,会直接修改原来的数组。
sorted
不会修改原来的数组,而是产生一个新的数组。
以上面的绝对值排序为例
>>> lst = [-9, -4, 3, -5, -2, -7, -8, -5, 8, -4]
>>> sorted(lst, key = lambda x: abs(x))
[-2, 3, -4, -4, -5, -5, -7, -8, 8, -9]
>>> lst # 此时原来的列表没有改变
[-9, -4, 3, -5, -2, -7, -8, -5, 8, -4]
>>> lst.sort(key = lambda x: abs(x))
>>> lst # 此时原来的列表改变了
[-2, 3, -4, -4, -5, -5, -7, -8, 8, -9]
未来练习一般推荐使用sorted
。
方法和函数的区别
- 方法是附在对象后面的,所以往往是
.
后面接的, - 函数是单独使用的
常见方法
>>> "123".isdigit()
True
>>> arr = [1,2,3]
>>> arr.append(5)
>>> arr
[1, 2, 3, 5]
>>> "15:30:22".split(":")
['15', '30', '22']
常见函数
>>> arr = [1, 2, 3, 4]
>>> len(arr)
4
>>> int("123")
123
>>> sum(arr)
10
方法的深入探究,
会在后面的类(class) 章节展开。
简单练习
1 按个位数字排序
给下面数组排序,按个位数字排序,个位数字大的在前。
nums = [
12, 133, 26, 19, 87, 31, 44, 125, 88
]
排好序之后的样子如下
[19, 88, 87, 26, 125, 44, 133, 12, 31]
2 字符串按长度排序
给字符串排序,用其字母的长度来排序,字母长的放前面。
words = [
"good",
"beauty",
"abandon",
"tree",
"problem",
"structure"
]
排好序之后的样子如下
['structure', 'abandon', 'problem', 'beauty', 'good', 'tree']
3 按总成绩排序
以下是某小组的成绩情况
每个元组中,记录的是姓名,三门科目的成绩。
按总成绩排序,成绩高的在前面。
scores = [
("zhang san", 80, 85, 88),
("li si", 90, 77, 88),
("wang wu", 65, 76, 78),
("zhao liu", 79, 88, 68),
("qian qi", 92, 80, 91),
("sun ba", 79, 80, 93),
]
排好序后如下
[
('qian qi', 92, 80, 91),
('li si', 90, 77, 88),
('zhang san', 80, 85, 88),
('sun ba', 79, 80, 93),
('zhao liu', 79, 88, 68),
('wang wu', 65, 76, 78)
]
没有意义的分割线
。
。
。
答案
sorted(nums, key = lambda num: num % 10, reverse=True)
sorted(words, key = lambda word: len(word), reverse=True)
sorted(scores, key = lambda item: item[1]+item[2]+ item[3], reverse=True)