Python 中的 Lambda 函数

PythonBeginner
立即练习

介绍

在这个 Lab 中,你将学习如何在 Python 中使用 lambda 函数。我们将从理解匿名函数(anonymous functions)的概念和 lambda 关键字开始,并将它们与传统的函数定义进行比较。然后,你将创建具有不同数量参数的简单 lambda 函数。

该 Lab 将进一步探讨如何有效地将 lambda 函数与 Python 内置函数(如 sorted)一起使用。最后,我们将讨论使用 lambda 函数的最佳实践,以确保你的代码可读且易于维护。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 95%。获得了学习者 100% 的好评率。

理解匿名函数和 Lambda

在这一步,我们将介绍 Python 中匿名函数的概念,重点关注 lambda 关键字。匿名函数是没有名称的函数,为定义简单、单表达式的函数提供了一种简洁的方式。

在 Python 中,我们通常使用 def 关键字来定义函数。例如,一个使数字翻倍的函数如下所示:

def double(x):
    return x * 2

print(double(10))

对于像这样的简单函数,lambda 提供了一种更紧凑的语法。让我们使用 lambda 创建相同的函数。

在左侧的 WebIDE 文件浏览器中,找到并打开文件 ~/project/lambda_example1.py。将以下代码添加到其中:

## Define a lambda function to double a number
double_lambda = lambda x: x * 2

## Call the lambda function and print the result
print(double_lambda(10))

其语法是 lambda arguments: expressionarguments 是输入,而 expression 是被评估并返回的单个操作。请注意,没有 return 关键字;返回是隐式的。

保存文件。要运行脚本,请在 WebIDE 中打开终端并执行以下命令:

python3 ~/project/lambda_example1.py

你应该在终端中看到输出。

20

这演示了 lambda 函数如何被赋值给一个变量并像常规函数一样被调用。

创建具有不同参数的 Lambda 函数

Lambda 函数非常灵活,可以定义零个、一个或多个参数。但是,它们始终仅限于单个表达式。在这一步,我们将探索如何创建具有不同数量参数的 lambda 函数。

首先,让我们创建一个不接受任何参数的 lambda 函数。这对于定义常量或简单的、可重复的操作非常有用。

从文件浏览器中打开文件 ~/project/lambda_example2.py。添加以下代码:

## Define a lambda function with no arguments
get_greeting = lambda: "Hello, World!"

## Call the lambda function and print the result
print(get_greeting())

接下来,让我们创建一个接受多个参数的 lambda 函数。我们将定义一个对两个数字求和的 lambda 函数。将此代码添加到同一个 lambda_example2.py 文件中:

## Define a lambda function that adds two numbers
add_numbers = lambda x, y: x + y

## Call the lambda function with two arguments and print the result
print(add_numbers(5, 3))

保存文件。现在,从终端运行脚本以查看两个输出:

python3 ~/project/lambda_example2.py

终端将显示来自两个 lambda 函数的结果。

Hello, World!
8

这表明 lambda 函数可以处理不同的参数配置,使其在各种简单任务中具有通用性。

sorted() 函数中使用 Lambda

Lambda 函数最常见的用途之一是作为高阶函数(接受其他函数作为参数的函数)的快速内联函数。一个典型的例子是 Python 的内置 sorted() 函数,它可以接受一个 key 参数。key 指定一个函数,该函数将在进行排序比较之前对每个元素调用。

想象你有一个元组(tuple)列表,每个元组代表一个产品及其价格。你想根据价格对这个列表进行排序。

在编辑器中打开文件 ~/project/lambda_sorted.py。添加以下代码:

## A list of tuples (product, price)
products = [('Laptop', 1200), ('Mouse', 25), ('Keyboard', 75)]

## Sort the list by price (the second element of each tuple) using a lambda function
sorted_products = sorted(products, key=lambda item: item[1])

## Print the sorted list
print(sorted_products)

在这段代码中,key=lambda item: item[1] 告诉 sorted() 使用每个元组的第二个元素(item[1],即价格)作为排序的值。这比使用 def 定义一个单独的函数要简洁得多。

保存文件并通过终端运行它:

python3 ~/project/lambda_sorted.py

你将看到产品列表按升序价格排序。

[('Mouse', 25), ('Keyboard', 75), ('Laptop', 1200)]

这种模式非常常见且有用,可以以简单易读的方式对复杂数据结构进行排序。

Lambda 高级技巧

在这一步,我们将探索使用 lambda 函数的一些稍微高级的方法,包括设置默认参数值和立即调用 lambda 函数。

与常规函数一样,lambda 函数可以带有默认值的参数。如果在函数调用期间未提供参数,这将提供一个后备值。

在编辑器中打开文件 ~/project/lambda_advanced.py。添加以下代码:

## Define a lambda function with a default parameter value
power = lambda base, exponent=2: base ** exponent

## Call the lambda function without the optional argument (uses default)
print(power(3))

## Call the lambda function with both arguments
print(power(3, 3))

另一种有趣的技术是定义并立即调用一个 lambda 函数。这被称为立即调用函数表达式(Immediately Invoked Function Expression, IIFE)。这对于创建一个临时的、一次性使用的函数来计算一个值而不会使命名空间混乱非常有用。

将以下代码添加到 lambda_advanced.py 文件中:

## Define and immediately invoke a lambda function to calculate a discounted price
price = 100
discount_percentage = 20
final_price = (lambda p, d: p * (1 - d / 100))(price, discount_percentage)

print(final_price)

保存文件并通过终端运行它:

python3 ~/project/lambda_advanced.py

输出将显示两个示例的结果。

9
27
80.0

虽然这些技术展示了 lambda 的灵活性,但请记住可读性是关键。如果逻辑变得复杂,标准的 def 函数通常是更好的选择。

最佳实践与可读性

在最后一步中,我们将讨论使用 lambda 函数的最佳实践。虽然 lambda 是编写简洁代码的强大工具,但应明智地使用它们,以保持代码的可读性和可维护性。

何时使用 lambda:

  • 作为高阶函数的参数: 这是主要的用例。像 sorted()map()filter() 这样的函数是 lambda 的完美选择。
  • 简单、简短的操作: 如果逻辑可以舒适且清晰地在一行内完成,那么 lambda 是一个好的选择。

何时避免使用 lambda:

  • 复杂逻辑: 如果你需要多条语句、复杂的条件逻辑或循环,请始终使用 def 函数。
  • 可读性问题: 如果一个 lambda 表达式一眼难以理解,那就违背了它的目的。一个带有描述性名称的命名函数会更好。
  • 可重用性: 如果你在多个地方需要相同的逻辑,请使用 def 将其定义一次,以遵循不要重复自己(Don't Repeat Yourself, DRY)的原则。

让我们看一个很好的、可读的示例,以加强最佳实践的用例。打开文件 ~/project/lambda_best_practice.py 并添加以下代码:

## A list of dictionaries
students = [
    {'name': 'Alice', 'grade': 88},
    {'name': 'Bob', 'grade': 95},
    {'name': 'Charlie', 'grade': 72}
]

## A good use of lambda: sorting a list of dictionaries by a value
sorted_by_grade = sorted(students, key=lambda student: student['grade'])

print("Sorted by grade:", sorted_by_grade)

## For comparison, a more complex task is better with a named function.
## For example, if you needed to apply a curve and check for a minimum score,
## a 'def' function would be much clearer than a complex lambda.
def process_grade(student):
    curved_grade = student['grade'] * 1.05
    return max(curved_grade, 75) ## Ensure a minimum score

processed_grades = [process_grade(s) for s in students]
print("Processed grades:", processed_grades)

保存文件并运行它:

python3 ~/project/lambda_best_practice.py

你将看到输出:

Sorted by grade: [{'name': 'Charlie', 'grade': 72}, {'name': 'Alice', 'grade': 88}, {'name': 'Bob', 'grade': 95}]
Processed grades: [92.4, 99.75, 75.60000000000001]

第一部分展示了 lambda 的清晰且恰当的用法。第二部分说明了命名函数更合适的场景。始终优先编写对你和他人来说易于阅读和理解的代码。

总结

在这个实验中,你学习了 Python lambda 函数的基础知识。你从理解它们的语法以及它们与使用 def 定义的标准函数有何不同开始。你练习了创建带有零个、一个和多个参数的 lambda 函数,并看到了如何将它们赋值给变量并调用它们。

一个关键收获是将 lambda 函数作为高阶函数的参数进行实际应用,特别是在使用 sorted() 来简洁地定义自定义排序逻辑时。我们还探索了默认参数和立即调用函数表达式(IIFE)等高级技术。最后,你回顾了使用 lambda 的最佳实践,强调虽然它们对于简单、一次性的用例非常强大,但可读性和可维护性应始终是首要考虑因素,对于更复杂的逻辑,应优先选择命名函数。