class: center, middle, inverse, title-slide .title[ # Introducción a Lambda Functions ] .subtitle[ ## MAD-UdelaR ] .author[ ### Daniel Miles Touya ] .date[ ### 2025-06-27 ] --- <style> .scroll-output { max-height: 300px; overflow-y: auto; background: #f9f9f9; border: 1px solid #ccc; padding: 10px; font-family: monospace; font-size: 70%; white-space: pre-wrap; } </style> # Lambda Functions > Una función `lambda` en Python es una forma **breve** de definir funciones **anónimas** (sin nombre explícito). >> Se escribe en una sola línea. >> Se usa para funciones simples, generalmente **de una sola expresión**. >> Equivalente a una función definida con `def`. --- # Lambda Functions .pull-left[ >Función normal ````python def suma(x, y): return x + y ```` ] .pull-right[ >Función lambda ````python lambda x, y: x + y ```` ] -- Aunque `lambda` define una función anónima, puedes **asignarla a una variable** y llamarla igual que una función creada con `def`. ````python f = lambda x, y: x + y print(f(3,4)) ```` -- O también puedes usarla directamente ````python (lambda x, y: x + y)(3,4) ```` --- # Lambda Functions: Posibles ventajas - **Sintaxis compacta**: se define en una sola línea, sin usar `def`. ```python lambda x: x + 1 ``` - **Útiles para funciones pequeñas y rápidas**, especialmente si solo se usan una vez. ```python pares = [(2, 3), (1, 5), (4, 1)] # Ordenamos por el segundo elemento de cada tupla (índice 1) pares.sort(key=lambda x: x[1]) ```` - **Se pueden usar como argumentos de otras funciones**, como `map`, `filter`, `sorted`, etc. ```python valores = [1, 2, 3] dobles = list(map(lambda x: x * 2, valores)) ``` - **Evitan “contaminar” el espacio de nombres**: al no darles nombre, no ocupan variables innecesarias. --- # Lambda Functions >Sintaxis de `lambda` ```python lambda argumentos: expresión ``` -> función anónima que recibe unos argumentos y devuelve el resultado de una expresión. >No tiene nombre. >No usa `return` (la expresión es devuelta automáticamente). >Se suele guardar en una variable si se quiere reutilizar. --- # Lambda Function: Una sola variable .pull-left[ ````python # Ordenar por longitud nombres = ["ana", "sofia", "lucía"] nombres.sort(key=lambda x: len(x)) ```` ] .pull-right[ > En Python, `lambda x: len(x)` significa: > “Una función que recibe un argumento `x` y devuelve `len(x)`”. ] -- Las funciones `lambda` pueden incluir condiciones simples usando `if ... else` en una **sola expresión**. ```python es_par = lambda x: "par" if x % 2 == 0 else "impar" print(es_par(4)) # 'par' print(es_par(7)) # 'impar' ```` --- # Lambda Functions: 2 variables >Simple ````python sumar = lambda x, y: x + y print(sumar(3, 5)) ```` -- >Ordenar ````python pares = [(3, 2), (1, 7), (2, 4)] # Ordenar por la suma de los dos elementos de cada tupla pares.sort(key=lambda par: par[0] + par[1]) ```` -- > Comparar ````python comparar = lambda x, y: "mayor" if x > y else "menor o igual" ```` -- >Dummy ````python pares = [(1, 5), (2, 3), (3, 4)] pares.sort(key=lambda par: (lambda _, y: y)(*par)) print(pares) ```` --- # Lambda Functions: Dentro de funciones `map` con `lambda` ```python numeros = [1, 2, 3, 4] # Elevar al cuadrado cada número cuadrados = list(map(lambda x: x ** 2, numeros)) print(cuadrados) # [1, 4, 9, 16] ``` -- > map con dos variables ```python a = [1, 2, 3] b = [10, 20, 30] # Suma elemento a elemento resultado = list(map(lambda x, y: x + y, a, b)) print(resultado) # [11, 22, 33] ``` --- # Lambda Functions: Dentro de funciones `map` con `lambda` > Condicional ````python a = [5, 2, 8] b = [3, 4, 8] # Comparar elementos y devolver el mayor resultado = list(map(lambda x, y: x if x > y else y, a, b)) print(resultado) # [5, 4, 8] ```` --- # Lambda Functions: Pandas >Venta ```python import pandas as pd import numpy as np # Simular datos np.random.seed(0) df = pd.DataFrame({ "ventas_2024": np.random.randint(80, 120, size=5), "ventas_2025": np.random.randint(90, 130, size=5) }, index=["región " + str(i) for i in range(1, 6)]) print(df.head()) ``` >Obetencion de año con más ventas ````python df["año_mayor_ventas"] = df.apply( lambda row: "2024" if row["ventas_2024"] > row["ventas_2025"] else "2025", axis=1 ) print(df.head()) ```` --- #Ejemplos avanzados >Función de función .pull-left[ ````python componer = lambda f, g: lambda x: f(g(x)) doble = lambda x: x * 2 incrementa = lambda x: x + 1 c_fg = componer(doble, incrementa) ```` ] -- .pull-right[ > ¿Qué hace `c_fx(3)`? 1.- Aplica incrementa(4) → 5 (g: x + 1) 2.- duplia el valor 5 → 5\*2 (f: x\*2) ] -- -> ¿Cuál es el orden de evaluación en esta función compuesta: `componer(doble, incrementa)(4)` ? 1.- Compone `f`→`doble` e `g`→`incremento` 2.- Devuelve `lambda x: f(g(x))`→ `lambda x: doble(incrementa(x))` --- # Lambada Functions >Ejemplo Aplicado en `sorted` con condicional ```python alumnos = [("Ana", 8), ("Luis", 6), ("Sofía", 9)] # Ordenar, pero considerar solo notas >= 7, otras como 0 ordenado = sorted(alumnos, key=lambda x: x[1] if x[1] >= 7 else 0) print(ordenado) ``` > Esto es útil cuando querés **ajustar el criterio de ordenamiento** con lógica. >> Ejercicio: transformarlo en `def` --- # Lambda `lambda` vs `def` — Tabla Comparativa | Característica | `lambda` | `def` | | ---------------- | --------------------------------------------- | ------------------------------------------------- | | Nombre | Anónima (sin nombre) | Con nombre definido | | Longitud | Una sola expresión | Múltiples líneas | | Uso principal | Funciones simples, en línea | Funciones más complejas o reutilizables | | Sintaxis | `lambda x: x * 2` | `def f(x): return x * 2` | | Retorno | Implícito | Explícito (`return`) | | Reutilización | Limitada / inmediata | Alta (puede usarse varias veces) | | Legibilidad | Menor (si es compleja) | Mayor (se puede documentar) | | Ejemplos comunes | `map`, `filter`, `sorted`, `apply`, `key=...` | Funciones generales en cualquier parte del código | --- # Lambda >¿Es `lambda` realmente funcional? >> Cosas que sí son funcionales en `lambda`: >> * Funciones como valores >> * Funciones anónimas >> * Closures >> * Composición >> * Inmutabilidad si la respetás >> Cosas que `lambda` **no permite** en Python: >>* Declaraciones (`print`, `while`, `for`, `assert`, etc.) >>* Múltiples líneas >>* Anotaciones o docstrings >>* Try/except