Skip to content

匿名函数

匿名函数

简介

匿名函数是指没有名字的函数,应用在需要一个函数,但是又不想费神去命名这个函数的场合。

在通常情况下,这样的函数只使用一次。

在 Python 中使用 lambda 表达式创建匿名函数。

  • lambda 表达式可用于任何需要函数对象的地方。
  • 在语法上,匿名函数只能是单个表达式。
  • 在语义上,它只是常规函数定义的语法糖。
  • lambda 表达式中不能使用 iffor-inwhilereturn 等语句, 但可以使用三目运算符

lambda 表达式

格式

result = lambda [arg1 [, arg2, .... , argn]]: expression
  • result:用于保存 lambda 表达式的引用
  • [arg1 [, arg2, .... , argn]]::可选,指定要传递的参数列表,多个参数间使用英文的逗号 进行分隔。
  • expression:必选,指定一个实现具体功能的表达式。如果有参数,那么在该表达式中将应用这些参数。

示例

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))

使用场景

  • 通常在这个函数只使用一次的场景下
  • 可以指定短小的回调函数

比如,在学习列表时的 sort() 排序方法,如果是简单的基本数据类型的数据,可以直接进行排序,但如果是复杂结构的数据,需要根据自定义的规则进行排序,此时就可以使用 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)

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)