Funciones lambda en Python
Una función lambda en Python es una función pequeña y anónima que se escribe en una sola línea.
El objetivo es crear funciones cuya lógica sea simple y rápida. No hay necesidad de definir una función completa para una tarea sencilla.
Su sintaxis es:
lambda argumentos: expresión
- lambda: Es la palabra clave con la que definimos la función.
- argumentos: La lista de argumentos que queremos pasarle (uno o más).
- expresión: El valor que devuelve la función.
Un ejemplo muy básico para que te hagas una idea es la suma de dos números. Para algo tan simple, no hace falta crear una función completa como:
def sumar(a, b): return a + b
Podemos hacer así:
sumar = lambda a, b: a + b print(sumar(5, 10)) # Devuelve 15
No deja de ser azúcar sintáctico por cierto 😉
Y permíteme decir, que, si ya conoces PHP, te será similar a las funciones flecha.
¡Sigamos!
Evidentemente su uso no se limita aquí, sino que son bastante útiles para pasar funciones como argumentos a otras funciones como son, por ejemplo: sorted, map, filter, etc.
Imagina que tienes una lista con números del 1 al 10 y quieres aplicar una operación a cada elemento de la misma. Por ejemplo, elevar al cuadrado cada número:
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] cuadrado = map(lambda x: x**2, numeros) print(list(cuadrado)) # Devuelve [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
O bien puedes usar filter para filtrar los elementos de la lista y devolver sólo los números pares:
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] pares = filter(lambda x: x % 2 == 0, numeros) print(list(pares)) # Devuelve [2, 4, 6, 8, 10]
Funciones lambda dentro de otras funciones
Empecemos por el ejemplo.
Imagina que tienes una plataforma de suscripción y dependiendo del pago del cliente le haces un descuento u otro. Es decir, si el cliente se suscribe durante 6 meses tiene un descuento, si se suscribe por un año, tendrá un descuento mayor…
¡Miremos el código!:
def generador_descuento(tipo_de_pago): """ Devuelve una función que aplica un descuento según el tipo de suscripción """ if tipo_de_pago == "Trimestral": return lambda precio: precio * 0.9 # 10% de descuento elif tipo_de_pago == "Semestral": return lambda precio: precio * 0.85 # 25% de descuento elif tipo_de_pago == "Anual": return lambda precio: precio * 0.5 # 50% de descuento else: return lambda precio: precio # No hay descuento # Crear funciones dinámicamente descuento_trimestre = generador_descuento("Trimestral") descuento_semestre = generador_descuento("Semestral") descuento_anual = generador_descuento("Anual") descuento_mensual = generador_descuento("Mensual") # Aplicar descuentos print(descuento_semestre(100)) # Salida: 85.0 print(descuento_anual(100)) # Salida: 50.0 print(descuento_mensual(100)) # Salida: 100
El ejemplo es bastante “simplón” pero nos sirve.
Según el tipo de suscripción que realiza el cliente, se devuelve una función lambda que aplica el descuento correspondiente.
¿Ves la ventaja de hacerlo así?
En vez de crear funciones completas y casi idénticas, creamos solo una principal y las otras, las definimos dinámicamente con lambda.
Crear una función solo para calcular el descuento trimestral, otra solo para calcular el descuento semestral… Seria redundante y poco escalable crear una función para cada tipo de descuento, ¿no crees?
Cuando conviene usarlas y cuando no
- Una función lambda es útil cuando necesitamos una función rápida y sencilla.
- Cuando no tenemos la necesidad de reutilizarla.
- Cuando necesitamos pasar funciones como argumentos a otras funciones (map, filter, sorted…).
¿Cuándo no es conveniente?
- Si la función que necesitamos crear será “algo” compleja, lo ideal en ese caso es crear una función normal y completa (usando def) y olvidarnos de lambda.
- Si tu intención es reutilizar la función más adelante, considera crear una función completa mejor.
- Si necesitamos documentar la función, las funciones lambda no lo permiten. En ese caso es mejor usar una función normal que permite docstrings.
Por cierto, personalmente creo que, si necesitas documentar una función lambda, es que la función será “algo” compleja, así que ya sabes, quizá sea mejor crear una función con def 😉
Recuerda siempre: «Una función lambda debe de ser breve.«
Ventajas y desventajas
Ventajas:
- Función pequeña y anónima que resulta útil para “tareas” sencillas o para pasarla como argumentos de otras funciones.
- También podemos destacar (como ya has visto) que no necesita un return, ya que la expresión después de los dos puntos se devuelve automáticamente.
- Se pueden usar dentro de otras funciones para personalizar la lógica.
- Otro punto es que solo necesitamos una línea de código y simplifican bastante el código.
Desventajas:
- Si la hacemos demasiado compleja al final resulta en código menos legible.
- De por si no permite declaraciones complejas. Por ejemplo, no permite ni bloques if, ni bucles, ni decoradores, etc.
- No la puedes documentar, pues no permite docstrings.
- “No se pueden” reutilizar.
En resumidas cuentas, la ventaja de las funciones lambda es su simplicidad y conveniencia para tareas pequeñas, simples y específicas.
Las desventajas aparecen cuando quieres usarlas para tareas complejas.
Y esto sería todo por ahora. Es un tema simple y conviene saberlo, ya que su uso es bastante frecuente.
Espero te haya servido y cualquier cosa déjamelo en comentarios.