Python anonymous function (lambda) usage guide

When writing Python code, you often encounter such a scenario: you only need to temporarily use a simple expression, such as one line of addition, subtraction, multiplication, division or conditional judgment, and do not want to use it specifically.defDefine a complete function. In this case, Python provides a lightweight way to define functions-anonymous function (lambda), which can help us write more compact code.

What is an anonymous function?

An anonymous function is a function that does not require passingdefA lightweight function that binds statement function names. They uselambdaKeyword definition, the entire function body is compressed into a single expression, and the calculation result of the expression will be automatically returned without explicit writing.return

Basic syntax

The basic syntax of anonymous functions is very concise:

lambda arguments: expression
  • lambda: Fixed keyword, indicating the beginning of defining an anonymous function.
  • arguments: Parameter list of the function, which can have no parameters or receive one or more parameters (multiple parameters are separated by commas).
  • expression: A legal Python expression. It cannot contain statements (e.g.print, assignment statements, etc.) and does not support multi-line logic. Ternary operators, function calls, etc. are allowed to be used as expressions.

ComparedefandlambdaYou can intuitively feel the difference by writing:

# 使用 def 定义(至少需要两行)
def square_def(x):
    return x * x

# 使用 lambda 定义(单行完成)
square_lambda = lambda x: x * x

print(square_def(5))   # 25
print(square_lambda(5)) # 25

It can be seen that for this extremely simple logic, lambda can save a lot of formatting code.

Usage example

The greatest value of lambda is that it can be used as a "use and throw away" function, directly passed to those higher-order functions that receive functions as parameters (such asmap()filter()sorted()etc.), can also be assigned to variables for short-term reuse, or used as return values ​​of other functions.

1. Cooperationmap()Batch processing elements

map()The same operation can be performed on each element in the iterable object. Combined with lambdas, "define function" and "apply to each element" can be done in one line.

# 生成 1~5 的平方列表
squares = list(map(lambda x: x * x, [1, 2, 3, 4, 5]))
print(squares)  # 输出: [1, 4, 9, 16, 25]

2. Cooperationfilter()Filter elements by condition

filter()will be retained in the iterable object so that the lambda expression returnsTrueelement, ideal for quickly defining filtering logic.

# 筛选 1~19 中的奇数
odd_numbers = list(filter(lambda n: n % 2 == 1, range(1, 20)))
print(odd_numbers)  # 输出: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

3. Multi-parameter lambda and assign value to variable

If the logic is simple but needs to be reused locally several times, you can bind the lambda to a variable name.

# 返回两个数中的较大值
max_two = lambda a, b: a if a > b else b  # 三目运算符是允许的单个表达式
print(max_two(10, 20))  # 20
print(max_two(-5, -3))  # -3

4. As the return value of a function (simple closure)

A lambda can be written inside an outer function and returned by the outer function. In this way, the inner lambda will "remember" the parameter values ​​of the outer function, forming a lightweight closure.

def make_adder(n):
    return lambda x: x + n

add_five = make_adder(5)   # add_five 现在是一个“给输入加 5”的函数
add_ten  = make_adder(10)  # add_ten  现在是“给输入加 10”的函数

print(add_five(10))  # 15
print(add_ten(20))   # 30

Core features of anonymous functions

  • Extremely lightweight: Suitable for temporary, one-time simple operations, eliminating the need fordefandreturnlayout overhead.
  • Single expression restriction: The function body can only write one expression and cannot contain statements or complex logic. Ternary operators, list comprehensions, function calls, etc. are all expressions and can be used.
  • Anonymous by default: The lambda itself has no name and does not pollute the namespace. If assigned to a variable, the variable name is equivalent to its "temporary alias".
  • First class citizen: completely equal to ordinary functions, can be assigned, passed as parameters, returned as values, and can also be stored in data structures.

Best practices in modern Python

1. Excess is never enough, use it in moderation

Lambda pursues simplicity, but if you write complex logic that is nested in multiple layers and is difficult to read in order to compress the number of lines, it will be counterproductive. When encountering situations where the logic is slightly complex, it is recommended to use it directlydefDefine named functions.

2. Need to be reused multiple times → give priority to usedef

Even if the logic is only one line, as long as it will be called at different places in the code, it should be given a meaningful name. Named functions are not only easy to understand and debug, but also convenient for later maintenance.

3. Python 3.5+ can add type hints

Lambda itself does not support adding type annotations directly, but you can usetyping.CallableMark the type of bound variables to improve the readability of the code and the IDE’s smart prompts.

from typing import Callable

# 声明这是一个接收 int 并返回 int 的函数
square_typed: Callable[[int], int] = lambda x: x ** 2
print(square_typed(5))  # 25

4. No difference in performance

No need to worry about lambda anddefperformance issues. The Python interpreter will compile them into almost identical bytecode, and the difference in operating efficiency will be negligible.

Exercises and Applications

Suppose there is originally a usedefExercises for defining odd numbers:

def is_odd(n):
    return n % 2 == 1

L = list(filter(is_odd, range(1, 20)))
print(L)

After rewriting it with lambda, the code becomes very compact:

L = list(filter(lambda n: n % 2 == 1, range(1, 20)))
print(L)

But again, ifis_oddThis logic is used in many places in the program, but it should still be kept independent.deffunction instead of copy-pasting the same lambda everywhere.

Extended knowledge: Comparison of list comprehensions and lambdas

In the Python community, list comprehensions (or generator expressions) tend to be preferred overmap() / filter()+ lambda is preferred because it tends to be semantically more intuitive and "Pythonic". Compare the two ways of writing:

# 计算平方:map + lambda  vs  列表推导式
squares_map   = list(map(lambda x: x * x, [1, 2, 3, 4, 5]))
squares_list  = [x * x for x in [1, 2, 3, 4, 5]]

# 筛选奇数:filter + lambda  vs  带 if 的列表推导式
odds_filter = list(filter(lambda n: n % 2 == 1, range(1, 20)))
odds_list   = [n for n in range(1, 20) if n % 2 == 1]

In most cases, list comprehensions are cleaner and more readable and can be a good alternative to lambdas.

Summarize

Anonymous functions (lambda) are a lightweight and practical feature in Python, designed for temporary, one-time, single-expression scenarios. Reasonable use can make the code more compact and reduce unnecessary boilerplate function definitions.

At the same time, please remember the following principles:

  • Use it first when the logic is complex or needs to be reused.defDefine named functions.
  • Lambda is very convenient when used for simple operations of high-order functions; but if the logic is slightly complex, you may wish to use list comprehensions instead or extract it as an independent function.
  • Keeping the readability of the code is always the first priority. Being concise and not obscure is the sign of good code.