Saltar al contenido
🐍 Curso de Python
/

Módulo 1 · Lección 39 de 59

Funciones lambda

Funciones anónimas de una sola expresión: qué son, dónde compensan de verdad y dónde es mejor escribir un def.

⏱ 10 min de lectura

Cuando ordenaste una lista de diccionarios por una de sus claves, escribiste algo como key=lambda empleado: empleado["salario"] y quizá lo copiaste sin entender del todo qué era esa palabra. Toca aclararlo.

Una lambda es una función sin nombre y de una sola expresión, que se escribe en el mismo sitio donde se usa. Sirve para esos casos en los que necesitas una función mínima, una única vez, y darle nombre y tres líneas propias sería más ruido que ayuda.

La sintaxis#

python
lambda parametros: expresion

La palabra lambda, los parámetros separados por comas, dos puntos y una expresión, cuyo valor se devuelve automáticamente. No se escribe return: está implícito.

Estas dos funciones son equivalentes:

python
def doblar(numero):
        return numero * 2


doblar_lambda = lambda numero: numero * 2

print(doblar(7), doblar_lambda(7))
Salida en pantalla
14 14

Lo que hace el segundo caso raro es precisamente que le hemos puesto nombre, algo que enseguida veremos que no se debe hacer. Una lambda está pensada para vivir dentro de la llamada a otra función, sin pasar nunca por una variable.

La limitación#

Una lambda solo admite una expresión. Una expresión es algo que produce un valor: una cuenta, una comparación, una llamada, un acceso a un diccionario, incluso un condicional en una línea. Lo que no cabe es una instrucción: no puedes poner un if de bloque, ni un for, ni varias líneas, ni asignar a una variable.

python
lambda nota: "Aprobado" if nota >= 5 else "Suspenso"    # válido: es una expresión
lambda nota: print(nota)                                 # válido, pero de mal gusto

Esta limitación no es un descuido, es el diseño: en cuanto tu función necesite más de una expresión, Python quiere que uses def. Y tiene razón, porque una lambda larga es ilegible.

Dónde tienen sentido de verdad#

En los parámetros key de sorted, min y max. Ahí la función es pura logística, solo dice de dónde sacar el valor con el que comparar, y es un caso perfecto para una lambda.

python
empleados = [
    {"nombre": "Ana", "salario": 32000, "antiguedad": 6},
    {"nombre": "Luis", "salario": 41000, "antiguedad": 2},
    {"nombre": "Marta", "salario": 28000, "antiguedad": 9},
]

por_salario = sorted(empleados, key=lambda empleado: empleado["salario"])
for empleado in por_salario:
        print(empleado["nombre"], empleado["salario"])

mejor_pagado = max(empleados, key=lambda empleado: empleado["salario"])
mas_veterano = max(empleados, key=lambda empleado: empleado["antiguedad"])
print(mejor_pagado["nombre"])
print(mas_veterano["nombre"])
Salida en pantalla
Marta 28000
Ana 32000
Luis 41000
Luis
Marta

sorted no ordena los diccionarios, que no se pueden comparar entre sí: llama a tu lambda con cada elemento y ordena por lo que esta devuelva. La lambda es la respuesta a "¿por cuál de sus datos los comparo?".

La expresión puede ser un cálculo, no solo un acceso:

python
pedidos = [
    ("Ana", 3, 19.99),
    ("Luis", 1, 49.50),
    ("Marta", 5, 7.25),
]

por_importe = sorted(pedidos, key=lambda pedido: pedido[1] * pedido[2], reverse=True)
for cliente, unidades, precio in por_importe:
        print(f"{cliente:<6} {unidades * precio:>7.2f}")
Salida en pantalla
Ana      59.97
Luis     49.50
Marta    36.25

map y filter#

Son dos funciones incorporadas que aplican otra función a todos los elementos de una colección. map transforma cada elemento; filter se queda con los que cumplen una condición. Se combinan a menudo con lambdas:

python
precios = [15.0, 30.0, 4.99, 80.0]

con_iva = list(map(lambda precio: round(precio * 1.21, 2), precios))
caros = list(filter(lambda precio: precio > 20, precios))
print(con_iva)
print(caros)
Salida en pantalla
[18.15, 36.3, 6.04, 96.8]
[30.0, 80.0]

Hace falta envolverlas en list() porque ambas devuelven un objeto perezoso que va produciendo los valores según se piden, no una lista.

Y ahora lo importante: en Python moderno esto casi siempre se escribe con una comprensión de lista.

python
con_iva = [round(precio * 1.21, 2) for precio in precios]
caros = [precio for precio in precios if precio > 20]
print(con_iva)
print(caros)
Salida en pantalla
[18.15, 36.3, 6.04, 96.8]
[30.0, 80.0]

Mismo resultado, sin lambda, sin list() alrededor y con una lectura de izquierda a derecha en lugar de de dentro hacia fuera. La comprensión es la forma idiomática, y es la que debes usar por defecto.

No le pongas nombre a una lambda#

python
calcular_iva = lambda precio: precio * 0.21
print(calcular_iva.__name__)


def calcular_iva_bien(precio):
        return precio * 0.21


print(calcular_iva_bien.__name__)
Salida en pantalla
<lambda>
calcular_iva_bien

Cuándo usar cada cosa#

SituaciónQué usar
Sacar un valor para key en sorted, min o maxlambda
Un método o función que ya existe y vale tal cualPásalo directamente: key=str.lower, key=len
Transformar o filtrar una lista enteraComprensión de lista
Una función que vas a reutilizar o que tiene nombre propiodef
Cualquier cosa que no quepa cómoda en una expresióndef, sin dudarlo