Funciones avanzadas
Lambda, *args/**kwargs, funciones como objetos, closures, decoradores y generators. Estas herramientas convierten código funcional en código elegante y profesional. Son las que aparecen en entrevistas técnicas y en el código de pandas y scikit-learn.
Concepto teórico
*args y **kwargs — parámetros flexibles
A veces no sabés de antemano cuántos argumentos va a recibir tu función. Python resuelve esto con dos mecanismos:
*args — captura cualquier cantidad de argumentos posicionales como una tupla:
def sumar_todo(*args):
return sum(args) # args es una tupla
sumar_todo(1, 2, 3) # args = (1, 2, 3) → 6
sumar_todo(10, 20, 30, 40) # args = (10, 20, 30, 40) → 100
**kwargs — captura cualquier cantidad de argumentos nombrados como un diccionario:
def crear_ficha(**kwargs):
for k, v in kwargs.items():
print(f" {k}: {v}")
crear_ficha(nombre="García", score=720, ciudad="BsAs")
# kwargs = {"nombre": "García", "score": 720, "ciudad": "BsAs"}
Podés combinar ambos con parámetros normales. El orden obligatorio es:
def f(normales, *args, **kwargs).
print(*args) acepta cualquier cantidad de valores. pd.read_csv(path, **kwargs) acepta
docenas de parámetros opcionales. dict(**kwargs) crea diccionarios. Entender *args/**kwargs te
permite leer el código fuente de pandas y scikit-learn.
Lambda — funciones anónimas
Una lambda es una función sin nombre, definida en una sola línea. Se usa cuando necesitás una
función simple y descartable — típicamente como argumento de sorted(), map(),
filter() o df.apply().
# Función normal
def doble(x):
return x * 2
# Equivalente lambda
doble = lambda x: x * 2
# Uso típico: como key en sorted
sorted(clientes, key=lambda c: c["score"])
f = lambda x: x*2). Si necesitás reusar la función, usá def. Las lambdas son para uso
inline y descartable (dentro de sorted, map, filter, apply).Funciones como objetos (first-class functions)
En Python, las funciones son objetos de primera clase. Esto significa que podés: asignarlas a variables, pasarlas como argumentos a otras funciones, devoverlas desde funciones, y guardarlas en listas o diccionarios.
Esto habilita patrones muy poderosos como callbacks, estrategias dinámicas y pipelines configurables.
Closures — funciones que recuerdan su contexto
Un closure es una función interna que "recuerda" las variables del scope donde fue creada, incluso después de que ese scope termine. Es como una función con memoria:
def crear_calculadora_iva(tasa):
def calcular(precio):
return precio * (1 + tasa) # "recuerda" tasa
return calcular
iva_21 = crear_calculadora_iva(0.21)
iva_105 = crear_calculadora_iva(0.105)
print(iva_21(1000)) # 1210.0
print(iva_105(1000)) # 1105.0
Decoradores — modificar funciones sin tocarlas
Un decorador es una función que envuelve otra función para agregarle funcionalidad sin
modificar su código. Usan la sintaxis @decorador arriba de la función. Son la base de frameworks
como Flask y Django:
def medir_tiempo(func):
def wrapper(*args, **kwargs):
import time
inicio = time.time()
resultado = func(*args, **kwargs)
print(f"{func.__name__} tardó {time.time()-inicio:.4f}s")
return resultado
return wrapper
@medir_tiempo
def procesar_datos(n):
return sum(range(n))
procesar_datos(1000000) # imprime el tiempo automáticamente
Generators — iteradores perezosos con yield
Un generator es una función que usa yield en vez de return. En vez
de calcular todos los resultados de una vez y guardarlos en memoria, genera uno a la vez. Ideal para datasets
grandes donde no querés cargar todo en RAM.
def generar_cuotas(capital, tasa, n):
saldo = capital
for mes in range(1, n+1):
interes = saldo * tasa
yield mes, interes, saldo # devuelve y "pausa"
saldo -= (capital / n)
for mes, interes, saldo in generar_cuotas(100000, 0.05, 6):
print(f"Mes {mes}: interés ${interes:,.0f}")
pd.read_csv(chunksize=1000) devuelve un
generator que lee 1000 filas por vez. sklearn usa generators internamente para datasets grandes.
Lambda se usa en df.apply(lambda x: ...) constantemente.
sorted(df, key=lambda x: x["col"]) es el patrón más común de lambda.
Ejemplos explicados paso a paso
Ejemplo 1: *args y **kwargs
Hacé clic en ▶ Ejecutar
Ejemplo 2: Lambda — funciones inline
Hacé clic en ▶ Ejecutar
Ejemplo 3: Funciones como objetos — pasar funciones como argumentos
Hacé clic en ▶ Ejecutar
Ejemplo 4: Closures y fábricas de funciones
Hacé clic en ▶ Ejecutar
Ejemplo 5: Decoradores y generators
Hacé clic en ▶ Ejecutar
Referencia rápida
| Concepto | Sintaxis | Cuándo usar |
|---|---|---|
*args |
def f(*args): |
Cantidad variable de args posicionales |
**kwargs |
def f(**kwargs): |
Cantidad variable de args nombrados |
| Lambda | lambda x: x*2 |
Inline en sorted/map/filter/apply |
| Func como arg | f(otra_func) |
Callbacks, estrategias, pipelines |
| Closure | def ext(): def int(): return int |
Fábricas de funciones, configuración |
| Decorador | @deco def f(): |
Logging, timing, validación, caching |
| Generator | def f(): yield x |
Datos grandes, iteración perezosa |
| Gen expression | (x for x in iter) |
Comprehension perezosa (sin memoria) |
| Patrón | Ejemplo práctico en análisis de datos |
|---|---|
| Lambda en sorted | sorted(clientes, key=lambda c: c["score"]) |
| Lambda en apply | df["cat"] = df["score"].apply(lambda s: "Alto" if s>700 else "Bajo") |
| **kwargs en configs | pd.read_csv("datos.csv", sep=";", encoding="latin-1") |
| Generator para chunks | for chunk in pd.read_csv("big.csv", chunksize=10000): |
Ejercicios
Ejercicio 1: Función con *args
Creá sumar(*numeros) que sume cualquier cantidad de números. Probá con 3 y con 5 argumentos.
Debe incluir 150.
Hacé clic en ▶ Ejecutar
Ejercicio 2: Lambda en sorted
Ordená [("GGAL",5200),("YPF",28000),("PAMP",3100)] por precio descendente con lambda. Debe
incluir YPF.
Hacé clic en ▶ Ejecutar
Ejercicio 3: **kwargs para crear registros
Creá crear_registro(**datos) que devuelva un diccionario. Probá creando un cliente. Debe incluir
García.
Hacé clic en ▶ Ejecutar
Ejercicio 4: Lambda con map y filter
Dada montos = [1500, -200, 3200, -500, 4100], usá filter con lambda para quedarte solo con
positivos, y map con lambda para aplicar IVA 21%. Debe incluir 10648 (suma con IVA).
Hacé clic en ▶ Ejecutar
Ejercicio 5: Closure — fábrica de calculadoras
Creá crear_convertidor(tasa) que devuelva una función que multiplique por la tasa. Usá para
crear a_dolares (÷1150) y a_pesos (×1150). Debe incluir USD.
Hacé clic en ▶ Ejecutar
Ejercicio 6: Función como argumento
Creá procesar_lista(datos, func) que aplique func a cada elemento. Probá con
str.upper y con una lambda. Debe incluir GARCÍA.
Hacé clic en ▶ Ejecutar
Ejercicio 7: Generator para cuotas
Creá un generator cuotas(capital, n) que yield las cuotas de un préstamo (capital/n). Consumilo
con for. Capital $120,000 en 6 cuotas. Debe incluir 20000.
Hacé clic en ▶ Ejecutar
Ejercicio 8: Decorador simple
Creá un decorador @log que imprima "Llamando a [nombre]..." antes de ejecutar la
función. Aplicalo a una función sumar(a,b). Debe incluir Llamando.
Hacé clic en ▶ Ejecutar
Ejercicio 9: Dispatch con dict de funciones
Creá un dict operaciones donde las claves son strings ("sumar","restar","multiplicar") y los
valores son lambdas. Usalo para ejecutar "multiplicar" con (15, 8). Debe incluir
120.
Hacé clic en ▶ Ejecutar
Ejercicio 10: Pipeline configurable con funciones avanzadas
Creá un sistema de pipeline donde: (1) definís funciones de transformación (limpiar, convertir, clasificar),
(2) las guardás en una lista pasos, (3) una función ejecutar_pipeline(dato, pasos)
aplica cada paso en orden. Procesá " $1,500.00 ". Debe incluir pipeline.
Hacé clic en ▶ Ejecutar
Resumen y conexión
*argscaptura posicionales como tupla.**kwargscaptura nombrados como dict.- Lambda es para funciones inline descartables:
sorted(data, key=lambda x: x["col"]). - Las funciones son objetos: podés pasarlas como argumentos, guardarlas en dicts, devolverlas.
- Closures son funciones que "recuerdan" variables de su scope de creación.
- Decoradores (
@deco) envuelven funciones para agregar funcionalidad (logging, timing, auth). - Generators (
yield) generan valores uno a uno — ideales para datos grandes.
En la siguiente lección (20 · Módulos de la stdlib) vas a explorar la biblioteca estándar de Python: math, datetime, random, json, os, collections — herramientas que vienen incluidas y que usás todos los días.
Recursos: Python docs — More on Functions · Functional Programming HOWTO