Aprende leyendo en orden

Expresiones lambda — Escribir funciones anónimas en una línea

Aprende las expresiones lambda de Python para escribir funciones anónimas en una sola línea.

En el artículo anterior sobre funciones de orden superior viste cómo pasar funciones como argumentos y valores de retorno. Definir una función nueva con def cada vez que necesitas entregar un callback significa que una operación de una línea de pronto ocupa 3 o 4 líneas.

Ahí entran las expresiones lambda (lambda) — te dejan escribir una función anónima en una sola línea. Perfectas para los pequeños fragmentos de lógica que no merecen un def completo.

Qué es una lambda — Comparada con def

La sintaxis es lambda args: expresión. El resultado de expresión se convierte directamente en el valor de retorno, y no escribes return (de hecho, hacerlo provoca un SyntaxError).

A diferencia de una función normal, una lambda no tiene nombre, así que no se puede llamar a menos que la asignes a una variable. El nombre de variable al que la asignas se convierte de hecho en el nombre de la función.

def vs lambda lado a lado
versión defdef add_tax(p): return int(p*1.1)versión lambdaadd_tax = lambda p: int(p*1.1)comprime a 1 línea
Una función pequeña que ocupa 4 líneas con def puede escribirse en 1 línea con lambda. No hace falta return — el valor de la expresión tras : se retorna tal cual.
# Escrita con def
def add_tax(price):
    return int(price * 1.1)

print(add_tax(980))   # 1078

# La misma lógica como lambda (sin return)
add_tax = lambda price: int(price * 1.1)

print(add_tax(980))   # 1078

Solo se permiten expresiones — Nada de sentencias

El cuerpo de una lambda solo puede contener una expresión (algo que evalúa a un valor). Las sentencias if, los bucles for y las asignaciones (=) no caben. En el momento en que quieras algo más elaborado, vuelve a def — esa es la decisión correcta.

Escribe una función de una línea que añada el 10% de IVA al precio de un producto.

① Construye una función que tome un precio y retorne el importe con impuestos como un entero.

② Llámala con 980 yenes y 2480 yenes e imprime cada resultado.

(Cuando la respuesta sea correcta, aparecerá la explicación.)

Editor Python

Ejecutar el código para ver el resultado

Más argumentos, expresiones condicionales y valores por defecto

Las lambdas también pueden tomar varios argumentos. Solo lístalos con comas, como lambda x, y: x * y.

También puedes usar argumentos por defecto igual que con def. Para alternar valores según una condición, mete una expresión condicional valor1 if condición else valor2 en el cuerpo.

# Varios argumentos
rect_area = lambda width, height: width * height
print(rect_area(4, 5))            # 20

# Argumento por defecto (omite rate para usar 0.1)
add_tax = lambda price, rate=0.1: int(price * (1 + rate))
print(add_tax(1000))              # 1100
print(add_tax(1000, 0.08))        # 1080

# Expresión condicional
judge_age = lambda age: "adulto" if age >= 20 else "menor"
print(judge_age(25))              # adulto
print(judge_age(17))              # menor

# Retornar varios valores como tupla
stats = lambda x, y: (x + y, x * y)
print(stats(3, 4))                # (7, 12)
Variaciones de argumentos en lambda
lambda x, y: x * yVarios argumentoslambda x, y=2: x**yArgumento por defectolambda x: "+" if x>0 else "-"Expresión condicional
lambda maneja varios argumentos, argumentos por defecto y ramificación con una expresión condicional con la misma sensación que def.

Escribe una sola línea que retorne un nivel de membresía (GOLD / SILVER / BRONZE) según los puntos. 1000 o más obtiene GOLD, 500 o más obtiene SILVER, y por debajo es BRONZE.

① Construye una función que tome los puntos y retorne el nivel.

② Llámala con 1500, 700 y 100, e imprime el resultado de cada una.

Editor Python

Ejecutar el código para ver el resultado

Emparejamiento con funciones de orden superior — Donde brillan las lambdas

Las lambdas se ganan el sueldo de verdad cuando quieres entregar una función desechable a una función de orden superior. Por ejemplo, el argumento key de sorted() es una función de orden superior que toma «una función que retorna la clave de ordenación a partir de cada elemento».

Para un orden de clasificación que no necesitas nombrar y reutilizar, escribir key=lambda x: x["price"] en línea en el punto de llamada es la forma más natural.

products = [
    {"name": "Cuaderno", "price": 480},
    {"name": "Bolígrafo", "price": 120},
    {"name": "Goma",     "price": 80},
]

# Ordena por precio ascendente (pasa una lambda en línea como key)
cheap_first = sorted(products, key=lambda item: item["price"])
for item in cheap_first:
    print(item["name"], item["price"])
# Goma 80
# Bolígrafo 120
# Cuaderno 480

# La misma función de orden superior process_list puede cambiar de comportamiento vía lambda
def process_list(numbers, func):
    for n in numbers:
        print(func(n))

process_list([1, 2, 3, 4], lambda x: x ** 2)
# 1
# 4
# 9
# 16
Cómo fluye una lambda hacia el key de sorted
products(lista de dicts)key=lambda item: item["price"]Nueva lista ordenadapor precio ascendenteaplicada a cada itemordenar por el valor clave

Ordena una lista de usuarios por puntuación, de mayor a menor. sorted() cambia a descendente cuando pasas reverse=True.

① Define users = [{"name": "Ana", "score": 78}, {"name": "Carlos", "score": 92}, {"name": "Marta", "score": 65}].

② Ordena con sorted(users, key=lambda u: u["score"], reverse=True) y asigna el resultado a ranking.

③ Itera con for u in ranking: e imprime print(u["name"], u["score"]).

Editor Python

Ejecutar el código para ver el resultado

Cuándo usar una lambda — y cuándo evitarla

Las lambdas son cómodas, pero usarlas en todas partes en realidad perjudica la legibilidad. La tabla de abajo lo resume: tira de lambdas para operaciones desechables de una línea, y quédate con def para cualquier cosa compleja o reutilizada.

SituaciónRecomendaciónRazón
Pasar a key de sorted, filter, maplambdaUna línea transmite la intención; no necesita nombre
Expresiones de una línea como precio con impuestoslambdaFunción nombrada corta sin necesidad de import
Lógica que necesita if / for / trydeflambda es solo expresiones; las sentencias provocan SyntaxError
Lógica reutilizada desde varios sitiosdefUn nombre transmite la intención y soporta tests y docs
Cuerpos de 3 o más líneasdefEncajarla en una lambda solo perjudica la legibilidad

No metas todo en una lambda

Apila tres expresiones condicionales anidadas o encadena unas cuantas llamadas a función y acabas con código que está en una línea pero es ilegible. En el momento en que pienses «me encantaría dejar un comentario explicando qué hace esta lambda», tira de def en su lugar.

Pasa una lambda en línea a una función de orden superior llamada process_list.

① Define def process_list(numbers, func): y llama a print(func(n)) dentro de for n in numbers:.

② Llama a process_list([1, 2, 3, 4, 5], lambda x: x ** 2) y confirma que se imprime el cuadrado de cada elemento en orden.

③ Llámala otra vez con process_list([1, 2, 3, 4, 5], lambda x: x * 10) y confirma que el comportamiento cambia solo con intercambiar la lambda.

Editor Python

Ejecutar el código para ver el resultado
QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1¿Cuál de las siguientes es una expresión lambda válida?

Pregunta 2¿Qué imprime este código?
f = lambda x, y=3: x ** y
print(f(2))

Pregunta 3¿Cuál de las siguientes es el uso más apropiado de una expresión lambda?