大爽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 is None (compare the elements directly).

key指定一个函数,该函数接受一个参数。
该函数用于从iterable的每个元素中提取用于比较的键 (例如 key=str.lower)。
默认值为 None (直接比较元素)。

reverse is a boolean value. If set to True, 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

https://docs.python.org/3/library/stdtypes.html#list.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)
posted @ 2021-12-01 18:38  大爽歌python编程辅导  阅读(147)  评论(0编辑  收藏  举报