匿名函数
大家好!这个章节我们来讨论匿名函数。你们可能在编程中遇到过需要一个简单的函数,但又不想为了这个函数起一个名字,这时候匿名函数就派上用场了。它们通常用于一些临时性的操作,避免了写出冗长的代码和命名。那么我们接下来一起看看什么是匿名函数,如何使用它们,以及它们的常见应用场景。
简介
匿名函数是指没有名字的函数,应用在需要一个函数,但是又不想费神去命名这个函数的场合。
在通常情况下,这样的函数只使用一次。
在 Python 中使用 lambda 表达式创建匿名函数。
lambda表达式可用于任何需要函数对象的地方。- 在语法上,匿名函数只能是单个表达式。
- 在语义上,它只是常规函数定义的语法糖。
lambda表达式中不能使用if、for-in、while、return等语句, 但可以使用三目运算符
匿名函数,顾名思义,就是没有名字的函数。在一些需要临时创建一个函数的场合,匿名函数就显得格外有用。我们用它来避免为某个简单函数专门定义一个名字。在 Python 中,我们通过 lambda 表达式来创建匿名函数。你可以理解为 lambda 就是定义匿名函数的快捷方式。下面是几个关于 lambda 表达式的关键点:它是一个简化的函数定义方式,通常用在你只需要使用一次的场景。语法上,lambda 函数只能包含一个表达式,不能有多个语句。你不能在 lambda 表达式中使用 if、for、while 等语句,但可以使用三目运算符,让逻辑更简洁。
lambda 表达式
# 格式
result = lambda [arg1 [, arg2, .... , argn]]: expression
result:用于保存lambda表达式的引用[arg1 [, arg2, .... , argn]]::可选,指定要传递的参数列表,多个参数间使用英文的逗号,进行分隔。expression:必选,指定一个实现具体功能的表达式。如果有参数,那么在该表达式中将应用这些参数。
首先,我们来看看 lambda 表达式的基本格式:result 是匿名函数的返回值,我们可以将它保存到变量中。arg1, arg2, 是可选的参数列表,用逗号分隔。expression 是函数体,它实现了函数的具体功能。需要注意的是,lambda 只能包含一个表达式,没有常规函数中的多个语句和逻辑。因此,匿名函数通常用于非常简单的操作。
示例:
def add(n1, n2):
return n1 + n2
result = add(1,2)
print(result)
add = lambda x,y: x+y
result = add(2,3)
print(result)
func = lambda x: x**2 if x > 3 else x**3
print(func(3))
让我们通过几个例子来深入理解匿名函数:在这个例子中,我们首先定义了一个常规的 add 函数来返回两个数的和。然后,我们用 lambda 表达式创建了一个简洁的匿名函数,它的功能和 add 函数是一样的。我们还展示了如何使用三目运算符在匿名函数中加入条件判断。例如,func 等于 lambda x冒号 x星号星号2 if x 大于 3 else x星号星号3 表示如果 x 大于 3,就返回 x 的平方,否则返回 x 的立方。
使用场景
- 通常在这个函数只使用一次的场景下
- 可以指定短小的回调函数
比如,在学习列表时的 sort() 排序方法,如果是简单的基本数据类型的数据,可以直接进行排序,但如果是复杂结构的数据,需要根据自定义的规则进行排序,此时就可以使用 lambda。
匿名函数特别适合那些只需要用一次的场合。举个例子,Python 的 sort 方法可以让我们对列表进行排序。如果我们排序的是简单的数据类型,比如数字或字符串,sort 方法就非常方便。但如果我们需要根据更复杂的规则来排序,比如对字典列表进行排序,匿名函数就显得非常有用了。我们可以在 sort 的 key 参数中直接传入一个 lambda 表达式来指定排序规则。
示例:
# 待排序的数据
students = [
{'name': 'Alice', 'id': '1001', 'class': 'Class1'},
{'name': 'Eve', 'id': '1005', 'class': 'Class2'},
{'name': 'Charlie', 'id': '1003', 'class': 'Class1'},
{'name': 'David', 'id': '1004', 'class': 'Class2'},
{'name': 'Bob', 'id': '1002', 'class': 'Class1'},
{'name': 'Frank', 'id': '1006', 'class': 'Class2'}
]
# TypeError: '<' not supported between instances of 'dict' and 'dict'
# students.sort()
# 以名字排序
students.sort(key=lambda stu: stu["name"])
for s in students:
print(s)
# 以ID降序排序
students.sort(key=lambda stu: stu["id"],reverse=True)
for s in students:
print(s)
假设我们有一个学生的字典列表,每个学生有 name、id 和 class 字段,我们可以使用匿名函数来按照 name 或 id 对学生进行排序。在这个例子中,students点sort。其中参数 key 就使用lambda表达式来指定排序的复杂规则。比如这里的排序规则就是使用传入的参数 stu,这是一个字典,具体是使用 stu 中的 name 这个 key 来进行排序。通过使用 lambda,我们避免了定义一个额外的函数来作为排序的规则,非常简洁。
sorted 函数实现原理
students = [
{'name': 'Alice', 'id': '1001', 'class': 'Class1'},
{'name': 'Eve', 'id': '1005', 'class': 'Class2'},
{'name': 'Charlie', 'id': '1003', 'class': 'Class1'},
{'name': 'David', 'id': '1004', 'class': 'Class2'},
{'name': 'Bob', 'id': '1002', 'class': 'Class1'},
{'name': 'Frank', 'id': '1006', 'class': 'Class2'}
]
def my_sorted(obj, key=None, reverse=False):
'''
列表排序,并返回一个新的列表,不改变原始列表的值
:param obj: 原始列表
:param key: 排序规则
:param reverse: 是否逆序,默认值为 False
:return: 排序后的列表
'''
# 定义一个新的空列表
new_stus = []
# 遍历原始列表
for s in obj:
# 遍历新列表
for n in new_stus:
# 如果有排序规则
if key:
# 如果规则下的原始列表中的值小于新列表中的值
if(key(s) < key(n)):
# 找到新列表中这个值的索引
idx = new_stus.index(n)
# 把原始列表的值插入到这个索引的位置
new_stus.insert(idx, s)
# 结束新列表的循环
break
# 如果没有排序规则
else:
# 如果原始列表中的值小于新列表中的值
if (s < n):
# 找到新列表中这个值的索引
idx = new_stus.index(n)
# 把原始列表的值插入到这个索引的位置
new_stus.insert(idx, s)
# 结束新列表的循环
break
# 如果原始列表中的值大于新列表中的所有值
else:
# 那么把这个值添加到新列表的最后
new_stus.append(s)
# 如果 reverse 为 True 返回逆序的新列表,否则返回排好序的新列表
return new_stus[::-1] if reverse else new_stus
students = my_sorted(students, key=lambda s: s["name"])
# students.sort(key=lambda s: s["name"])
# students = sorted(students, key=lambda s: s["name"])
# students = [1,4,2,6,7,8,4,3,3]
# students = my_sorted(students, reverse=True)
print(students)
for s in students:
print(s)
Python 中的 sorted 函数也可以用 lambda 表达式来进行排序。其实,sorted 背后是使用了类似的排序算法。我们也可以自己实现一个简单的排序函数,理解一下排序是如何工作的。在这个例子中,我们通过自定义的 my_sorted 函数模拟了 sorted 的排序过程。函数通过 key 和 reverse 参数实现了对数据的排序,也展示了如何使用 lambda 表达式作为自定义排序规则。
总结
- lambda 表达式
- 匿名函数使用场景
- sorted 函数实现原理
最后我们来总结一下。这个章节学习了关于 lambda 表达式和匿名函数 的内容。匿名函数非常简洁,特别适合在需要一次性函数的场合。通过 lambda 表达式,我们可以避免额外的函数定义,直接在需要的地方定义一个简单的操作。希望大家在实践中能够灵活运用 lambda,让代码更加简洁高效!