Funciones lambda en Python: cuándo usarlas y cuándo no

Una lambda es una función anónima de una sola expresión. Python las permite, pero la comunidad tiene opiniones claras sobre cuándo usarlas y cuándo definir un def normal. Usarlas correctamente mejora la legibilidad; usarlas mal produce código difícil de depurar.

Sintaxis básica

# Función normal
def cuadrado(x):
    return x ** 2

# Lambda equivalente
cuadrado = lambda x: x ** 2

print(cuadrado(5))  # 25

# Lambda con múltiples parámetros
producto = lambda x, y: x * y
print(producto(3, 4))  # 12

Usos idiomáticos: sorted(), filter() y map()

El caso más frecuente es pasar una lambda como parámetro key a sorted():

personas = [
    {"nombre": "Ana", "edad": 28},
    {"nombre": "Luis", "edad": 22},
    {"nombre": "María", "edad": 35},
]

# Ordenar por edad
por_edad = sorted(personas, key=lambda p: p["edad"])
# Ordenar por nombre descendente
por_nombre = sorted(personas, key=lambda p: p["nombre"], reverse=True)

# Ordenar tuplas por el segundo elemento
pares = [(1, 'b'), (3, 'a'), (2, 'c')]
print(sorted(pares, key=lambda t: t[1]))  # [(3, 'a'), (1, 'b'), (2, 'c')]

Lambdas con filter() y map()

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# filter() — devuelve iterador con los que cumplen la condición
pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares)  # [2, 4, 6, 8, 10]

# map() — transforma cada elemento
cuadrados = list(map(lambda x: x ** 2, numeros))
print(cuadrados)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# Alternativa con comprehension (más legible para muchos)
pares_c     = [x for x in numeros if x % 2 == 0]
cuadrados_c = [x ** 2 for x in numeros]

Lambdas en closures

def multiplicador(factor):
    return lambda x: x * factor

doble  = multiplicador(2)
triple = multiplicador(3)

print(doble(5))   # 10
print(triple(5))  # 15

# Útil para pipelines de transformación
operaciones = [lambda x: x + 1, lambda x: x * 2, lambda x: x - 3]
valor = 5
for op in operaciones:
    valor = op(valor)
print(valor)  # (5+1)*2-3 = 9

El bug clásico: captura de variables en bucles

# MAL: todas las lambdas capturan la MISMA variable i
funciones = [lambda x: x + i for i in range(5)]
print(funciones[0](10))  # 14, no 10! (i vale 4 al final del bucle)
print(funciones[2](10))  # 14

# BIEN: captura el valor en el momento de creación
funciones = [lambda x, i=i: x + i for i in range(5)]
print(funciones[0](10))  # 10
print(funciones[2](10))  # 12

Cuándo usar def en lugar de lambda

# MAL: lambda demasiado compleja
procesador = lambda datos: [x.strip().lower() for x in datos if x.strip()]

# BIEN: def con nombre descriptivo
def normalizar_entradas(datos):
    """Limpia y normaliza una lista de cadenas."""
    return [x.strip().lower() for x in datos if x.strip()]

Usa lambda cuando la función es trivial y se usa una sola vez como argumento. En cuanto la lógica necesite comentario, nombre descriptivo o más de una expresión, define una función normal con def.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP