Python
Tutorial Python: Composición de funciones
Aprende la composición de funciones en Python con ejemplos prácticos y la nueva función functools.compose para crear pipelines eficientes.
Aprende Python y certifícatePrincipios de composición funcional
La composición de funciones es un concepto fundamental en la programación funcional que nos permite combinar múltiples funciones para crear transformaciones más complejas. En su esencia, la composición funcional consiste en tomar la salida de una función y pasarla como entrada a otra, creando así un flujo de datos transformativo.
Imagina una cadena de producción en una fábrica: cada estación realiza una tarea específica sobre un producto que va avanzando por la línea. De manera similar, en la composición funcional cada función representa una "estación" que transforma los datos que fluyen a través de ella.
Definición matemática
Matemáticamente, la composición de funciones se representa como (f ∘ g)(x) = f(g(x)), donde primero se aplica la función g y luego se aplica f al resultado. En Python, esto se traduce de manera natural:
def g(x):
return x * 2
def f(x):
return x + 1
# Composición manual
resultado = f(g(5)) # Primero g(5) = 10, luego f(10) = 11
print(resultado) # 11
Ventajas de la composición funcional
La composición de funciones ofrece varias ventajas significativas:
- Modularidad: Cada función realiza una tarea específica y bien definida.
- Reutilización: Las funciones pueden combinarse de diferentes maneras para resolver diversos problemas.
- Legibilidad: El código expresa claramente la secuencia de transformaciones.
- Mantenibilidad: Es más fácil probar y depurar funciones pequeñas e independientes.
Funciones puras
Para que la composición funcional sea efectiva, es recomendable trabajar con funciones puras. Una función pura:
- Siempre produce el mismo resultado para los mismos argumentos
- No tiene efectos secundarios (no modifica variables externas)
- No depende del estado externo
# Función pura
def incrementar(x):
return x + 1
# Función impura (depende del estado externo)
contador = 0
def incrementar_contador():
global contador
contador += 1
return contador
Las funciones puras son ideales para la composición porque su comportamiento es predecible y no interfieren entre sí.
Composición de múltiples funciones
La composición puede extenderse a más de dos funciones, creando una cadena de transformaciones:
def cuadrado(x):
return x * x
def duplicar(x):
return x * 2
def sumar_uno(x):
return x + 1
# Composición de tres funciones
valor = 3
resultado = sumar_uno(duplicar(cuadrado(valor)))
print(resultado) # 3² = 9, 9*2 = 18, 18+1 = 19
Esta forma de anidar llamadas a funciones puede volverse difícil de leer cuando hay muchas transformaciones. Podemos mejorar la legibilidad utilizando variables intermedias:
valor = 3
paso1 = cuadrado(valor) # 9
paso2 = duplicar(paso1) # 18
resultado = sumar_uno(paso2) # 19
Orden de aplicación
Es importante entender que en la composición funcional, las funciones se aplican de adentro hacia afuera. Esto puede resultar confuso al leer el código, ya que leemos de izquierda a derecha, pero las funciones se ejecutan en orden inverso:
# En esta expresión:
resultado = f(g(h(x)))
# El orden de ejecución es:
# 1. h(x)
# 2. g(resultado_de_h)
# 3. f(resultado_de_g)
Aplicación parcial y currificación
La aplicación parcial y la currificación son técnicas que facilitan la composición funcional:
from functools import partial
def multiplicar(a, b):
return a * b
# Aplicación parcial: creamos una nueva función que multiplica por 2
duplicar = partial(multiplicar, 2)
# Ahora podemos usar esta función en composiciones
resultado = duplicar(5) # 10
Ejemplo práctico: procesamiento de datos
Veamos un ejemplo práctico de composición funcional para procesar una lista de números:
def filtrar_pares(numeros):
return [n for n in numeros if n % 2 == 0]
def cuadrados(numeros):
return [n * n for n in numeros]
def suma_total(numeros):
return sum(numeros)
# Composición para calcular la suma de los cuadrados de números pares
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
resultado = suma_total(cuadrados(filtrar_pares(numeros)))
print(resultado) # 2² + 4² + 6² + 8² + 10² = 4 + 16 + 36 + 64 + 100 = 220
Este ejemplo muestra cómo podemos componer tres operaciones distintas (filtrado, transformación y reducción) para crear un procesamiento de datos más complejo.
Composición con funciones de orden superior
Las funciones de orden superior (funciones que toman o devuelven otras funciones) son herramientas poderosas para la composición funcional:
def componer_dos(f, g):
"""Compone dos funciones: f(g(x))"""
def composicion(x):
return f(g(x))
return composicion
# Creamos funciones simples
sumar_cinco = lambda x: x + 5
multiplicar_por_tres = lambda x: x * 3
# Componemos las funciones
f_compuesta = componer_dos(sumar_cinco, multiplicar_por_tres)
# Usamos la función compuesta
resultado = f_compuesta(4) # 4 * 3 = 12, 12 + 5 = 17
print(resultado) # 17
Esta función componer_dos
nos permite crear una nueva función que representa la composición de otras dos, lo que facilita la reutilización y la legibilidad.
Composición generalizada
Podemos generalizar la composición para trabajar con un número arbitrario de funciones:
def componer(*funciones):
"""
Compone múltiples funciones de derecha a izquierda.
componer(f, g, h)(x) es equivalente a f(g(h(x)))
"""
def composicion(x):
resultado = x
# Aplicamos las funciones en orden inverso
for f in reversed(funciones):
resultado = f(resultado)
return resultado
return composicion
# Definimos funciones simples
sumar_uno = lambda x: x + 1
duplicar = lambda x: x * 2
cuadrado = lambda x: x * x
# Componemos las funciones
pipeline = componer(sumar_uno, duplicar, cuadrado)
# Usamos la composición
resultado = pipeline(3) # 3² = 9, 9*2 = 18, 18+1 = 19
print(resultado) # 19
Esta implementación de componer
nos permite crear "pipelines" de procesamiento de datos de forma clara y concisa.
Implementación de composición en Python
Ahora que comprendemos los principios teóricos de la composición funcional, vamos a explorar diferentes formas de implementarla en Python. El lenguaje ofrece varias técnicas para crear composiciones de funciones de manera elegante y eficiente.
Implementación básica con funciones anidadas
La forma más directa de implementar composición en Python es mediante el anidamiento de llamadas a funciones:
def duplicar(x):
return x * 2
def incrementar(x):
return x + 1
# Composición mediante anidamiento
resultado = incrementar(duplicar(5)) # 5 → 10 → 11
print(resultado) # 11
Sin embargo, este enfoque se vuelve difícil de leer cuando tenemos muchas funciones. Podemos mejorar esto creando una función auxiliar que implemente la composición:
def componer_dos(f, g):
"""Crea una nueva función que aplica f después de g"""
return lambda x: f(g(x))
# Creamos una función compuesta
incrementar_duplicado = componer_dos(incrementar, duplicar)
# La usamos como cualquier otra función
resultado = incrementar_duplicado(5) # 11
print(resultado)
Composición con múltiples funciones
Podemos extender nuestra implementación para manejar un número arbitrario de funciones:
def componer(*funciones):
"""
Compone varias funciones, de derecha a izquierda.
componer(f, g, h)(x) equivale a f(g(h(x)))
"""
if not funciones:
return lambda x: x # Función identidad si no hay funciones
def composicion(x):
resultado = x
for f in reversed(funciones): # Aplicamos de derecha a izquierda
resultado = f(resultado)
return resultado
return composicion
# Definimos algunas funciones simples
cuadrado = lambda x: x * x
duplicar = lambda x: x * 2
incrementar = lambda x: x + 1
# Componemos las tres funciones
pipeline = componer(incrementar, duplicar, cuadrado)
# Usamos la función compuesta
valor = 3
resultado = pipeline(valor) # 3² = 9, 9*2 = 18, 18+1 = 19
print(resultado) # 19
Esta implementación nos permite crear pipelines de procesamiento de manera clara y concisa.
Composición con operador de tubería
Python no tiene un operador de tubería nativo como otros lenguajes funcionales (por ejemplo, el operador |>
en F# o Elixir), pero podemos simular uno usando clases:
class Pipe:
"""Clase para simular un operador de tubería"""
def __init__(self, valor):
self.valor = valor
def __or__(self, funcion):
"""Implementa el operador | para aplicar funciones"""
return Pipe(funcion(self.valor))
def valor_final(self):
"""Devuelve el valor resultante"""
return self.valor
# Uso del operador de tubería simulado
resultado = (
Pipe(3)
| cuadrado # 9
| duplicar # 18
| incrementar # 19
).valor_final()
print(resultado) # 19
Este enfoque permite escribir composiciones de funciones de manera más legible, siguiendo un flujo de izquierda a derecha que refleja mejor el orden de las transformaciones.
Composición con reducción
Otra forma elegante de implementar la composición es utilizando functools.reduce
:
from functools import reduce
def componer_con_reduce(*funciones):
"""Compone funciones usando reduce"""
def componer_dos(f, g):
return lambda x: f(g(x))
# Si no hay funciones, devolvemos la función identidad
if not funciones:
return lambda x: x
# Componemos las funciones de derecha a izquierda
return reduce(componer_dos, funciones)
# Creamos una composición
pipeline = componer_con_reduce(incrementar, duplicar, cuadrado)
# La utilizamos
resultado = pipeline(3) # 19
print(resultado)
Composición con decoradores
Los decoradores de Python también pueden utilizarse para implementar composición de funciones:
def aplicar_despues(g):
"""Decorador que aplica g después de la función decorada"""
def decorador(f):
def funcion_compuesta(x):
return g(f(x))
return funcion_compuesta
return decorador
# Usamos decoradores para componer funciones
@aplicar_despues(incrementar)
@aplicar_despues(duplicar)
def calcular(x):
return x * x
# Esta definición equivale a: incrementar(duplicar(calcular(x)))
resultado = calcular(3) # 19
print(resultado)
Composición con listas de comprensión
Para operaciones sobre colecciones, podemos usar listas de comprensión anidadas como forma de composición:
numeros = [1, 2, 3, 4, 5]
# Composición mediante listas de comprensión anidadas
resultado = sum([n * 2 for n in [x * x for x in numeros if x % 2 == 0]])
print(resultado) # 40 (2² * 2 + 4² * 2 = 8 + 32 = 40)
Sin embargo, este enfoque puede volverse difícil de leer. Una alternativa más clara es usar funciones intermedias:
def filtrar_pares(nums):
return [n for n in nums if n % 2 == 0]
def calcular_cuadrados(nums):
return [n * n for n in nums]
def duplicar_todos(nums):
return [n * 2 for n in nums]
# Composición más legible
resultado = sum(duplicar_todos(calcular_cuadrados(filtrar_pares(numeros))))
print(resultado) # 40
Composición con generadores
Los generadores ofrecen una forma eficiente de implementar composición para procesamiento de datos, especialmente para conjuntos grandes:
def filtrar_pares_gen(nums):
for n in nums:
if n % 2 == 0:
yield n
def calcular_cuadrados_gen(nums):
for n in nums:
yield n * n
def duplicar_todos_gen(nums):
for n in nums:
yield n * 2
# Composición con generadores
numeros = range(1, 6) # 1, 2, 3, 4, 5
pipeline = duplicar_todos_gen(calcular_cuadrados_gen(filtrar_pares_gen(numeros)))
resultado = sum(pipeline)
print(resultado) # 40
Esta implementación es más eficiente en memoria porque procesa los elementos uno por uno, sin crear listas intermedias.
Composición con map y filter
Las funciones map
y filter
son herramientas fundamentales para la programación funcional en Python y se prestan naturalmente a la composición:
numeros = [1, 2, 3, 4, 5]
# Composición con map y filter
pares = filter(lambda x: x % 2 == 0, numeros)
cuadrados = map(lambda x: x * x, pares)
duplicados = map(lambda x: x * 2, cuadrados)
resultado = sum(duplicados)
print(resultado) # 40
Composición con funciones de orden superior
Podemos crear funciones de orden superior que faciliten patrones comunes de composición:
def componer_transformaciones(transformaciones):
"""Compone una serie de transformaciones sobre colecciones"""
def aplicar(datos):
resultado = datos
for transformacion in transformaciones:
resultado = transformacion(resultado)
return resultado
return aplicar
# Definimos transformaciones
filtrar = lambda datos: filter(lambda x: x % 2 == 0, datos)
elevar_cuadrado = lambda datos: map(lambda x: x * x, datos)
duplicar = lambda datos: map(lambda x: x * 2, datos)
# Componemos las transformaciones
pipeline = componer_transformaciones([filtrar, elevar_cuadrado, duplicar])
# Aplicamos la composición
numeros = [1, 2, 3, 4, 5]
resultado = sum(pipeline(numeros))
print(resultado) # 40
Composición con clases
También podemos implementar la composición utilizando clases, lo que puede ser útil para crear pipelines más complejos:
class Transformacion:
"""Clase base para transformaciones componibles"""
def __init__(self, siguiente=None):
self.siguiente = siguiente
def procesar(self, datos):
resultado = self._aplicar(datos)
if self.siguiente:
return self.siguiente.procesar(resultado)
return resultado
def _aplicar(self, datos):
"""Método a implementar por las subclases"""
return datos
def __rshift__(self, otra):
"""Implementa el operador >> para componer transformaciones"""
if self.siguiente:
self.siguiente >> otra
else:
self.siguiente = otra
return self
# Implementamos transformaciones específicas
class FiltrarPares(Transformacion):
def _aplicar(self, datos):
return [x for x in datos if x % 2 == 0]
class CalcularCuadrados(Transformacion):
def _aplicar(self, datos):
return [x * x for x in datos]
class Duplicar(Transformacion):
def _aplicar(self, datos):
return [x * 2 for x in datos]
# Componemos las transformaciones
pipeline = FiltrarPares() >> CalcularCuadrados() >> Duplicar()
# Aplicamos la composición
numeros = [1, 2, 3, 4, 5]
resultado = sum(pipeline.procesar(numeros))
print(resultado) # 40
Este enfoque orientado a objetos es más verboso pero ofrece mayor flexibilidad para implementar transformaciones complejas y mantener estado entre etapas del pipeline.
Composición con diccionarios de configuración
Para casos donde necesitamos configurar dinámicamente nuestras composiciones:
def crear_pipeline(configuracion):
"""Crea un pipeline basado en una configuración"""
transformaciones = []
if configuracion.get('filtrar_pares', False):
transformaciones.append(lambda datos: [x for x in datos if x % 2 == 0])
if configuracion.get('calcular_cuadrados', False):
transformaciones.append(lambda datos: [x * x for x in datos])
if configuracion.get('duplicar', False):
transformaciones.append(lambda datos: [x * 2 for x in datos])
def pipeline(datos):
resultado = datos
for t in transformaciones:
resultado = t(resultado)
return resultado
return pipeline
# Configuramos y creamos el pipeline
config = {
'filtrar_pares': True,
'calcular_cuadrados': True,
'duplicar': True
}
pipeline = crear_pipeline(config)
numeros = [1, 2, 3, 4, 5]
resultado = sum(pipeline(numeros))
print(resultado) # 40
Esta técnica es útil para sistemas configurables donde las transformaciones pueden variar según las necesidades.
functools.compose
A partir de Python 3.13, el módulo functools
incorpora una nueva función llamada compose
que simplifica enormemente la implementación de la composición funcional. Esta adición oficial al lenguaje reconoce la importancia de la composición de funciones como un patrón fundamental en la programación funcional.
La función compose
permite combinar múltiples funciones en una sola operación, aplicándolas de derecha a izquierda, siguiendo la notación matemática tradicional de composición (f ∘ g)(x) = f(g(x)).
Sintaxis básica
La sintaxis de functools.compose
es simple y directa:
from functools import compose
# Definimos funciones simples
def duplicar(x):
return x * 2
def sumar_uno(x):
return x + 1
# Componemos las funciones
f_compuesta = compose(sumar_uno, duplicar)
# Usamos la función compuesta
resultado = f_compuesta(5) # 5 → 10 → 11
print(resultado) # 11
En este ejemplo, compose(sumar_uno, duplicar)
crea una nueva función que primero aplica duplicar
y luego sumar_uno
al resultado.
Orden de aplicación
Es importante entender que compose
aplica las funciones de derecha a izquierda, lo que puede resultar contraintuitivo para programadores acostumbrados a leer código de izquierda a derecha:
from functools import compose
def cuadrado(x):
return x * x
def duplicar(x):
return x * 2
def sumar_uno(x):
return x + 1
# En esta composición:
f = compose(sumar_uno, duplicar, cuadrado)
# El orden de aplicación es:
# 1. cuadrado (la función más a la derecha)
# 2. duplicar
# 3. sumar_uno (la función más a la izquierda)
resultado = f(3) # 3² = 9, 9*2 = 18, 18+1 = 19
print(resultado) # 19
Este orden sigue la notación matemática estándar para la composición de funciones, donde (f ∘ g ∘ h)(x) = f(g(h(x))).
Ventajas sobre implementaciones manuales
Aunque en secciones anteriores vimos cómo implementar la composición manualmente, functools.compose
ofrece varias ventajas:
- Código más conciso: No necesitamos escribir nuestra propia función de composición.
- Optimización interna: La implementación oficial está optimizada para rendimiento.
- Claridad de intención: El uso de una función estándar comunica claramente la intención del código.
- Mantenibilidad: Dependemos de la biblioteca estándar en lugar de código personalizado.
Composición con funciones de múltiples argumentos
compose
funciona naturalmente con funciones que toman un solo argumento, pero ¿qué ocurre con funciones que requieren múltiples parámetros? Podemos usar técnicas como la aplicación parcial o funciones lambda:
from functools import compose, partial
def multiplicar(a, b):
return a * b
def sumar(a, b):
return a + b
# Aplicación parcial para crear funciones de un solo argumento
multiplicar_por_2 = partial(multiplicar, 2)
sumar_3 = partial(sumar, 3)
# Ahora podemos componer estas funciones
pipeline = compose(sumar_3, multiplicar_por_2)
resultado = pipeline(5) # 5*2 = 10, 10+3 = 13
print(resultado) # 13
Uso con funciones de procesamiento de colecciones
compose
es particularmente útil cuando trabajamos con funciones que procesan colecciones de datos:
from functools import compose
def filtrar_pares(numeros):
return [n for n in numeros if n % 2 == 0]
def calcular_cuadrados(numeros):
return [n * n for n in numeros]
def sumar_lista(numeros):
return sum(numeros)
# Componemos las funciones para crear un pipeline de procesamiento
pipeline = compose(sumar_lista, calcular_cuadrados, filtrar_pares)
# Aplicamos el pipeline a una lista de números
numeros = [1, 2, 3, 4, 5, 6]
resultado = pipeline(numeros) # Filtra [2,4,6], calcula [4,16,36], suma 56
print(resultado) # 56
Este patrón es muy común en el procesamiento de datos, donde necesitamos aplicar varias transformaciones secuenciales a un conjunto de datos.
Combinación con otras funciones de functools
compose
se integra perfectamente con otras funciones del módulo functools
, creando combinaciones potentes:
from functools import compose, partial, reduce
# Función que aplica una operación a todos los elementos
def map_operacion(operacion, lista):
return [operacion(x) for x in lista]
# Creamos operaciones parciales
duplicar_lista = partial(map_operacion, lambda x: x * 2)
elevar_al_cuadrado = partial(map_operacion, lambda x: x * x)
# Función para filtrar elementos
def solo_mayores_que(umbral, lista):
return [x for x in lista if x > umbral]
filtrar_mayores_que_10 = partial(solo_mayores_que, 10)
# Componemos las operaciones
pipeline = compose(sum, filtrar_mayores_que_10, duplicar_lista, elevar_al_cuadrado)
# Aplicamos el pipeline
numeros = [1, 2, 3, 4, 5]
resultado = pipeline(numeros) # [1,4,9,16,25] → [2,8,18,32,50] → [18,32,50] → 100
print(resultado) # 100
Ejemplo práctico: procesamiento de texto
Veamos un ejemplo más práctico de procesamiento de texto utilizando compose
:
from functools import compose
import re
def normalizar_texto(texto):
"""Convierte a minúsculas y elimina caracteres especiales"""
return re.sub(r'[^\w\s]', '', texto.lower())
def tokenizar(texto):
"""Divide el texto en palabras"""
return texto.split()
def eliminar_stopwords(tokens):
"""Elimina palabras comunes sin valor semántico"""
stopwords = {'el', 'la', 'los', 'las', 'un', 'una', 'y', 'de', 'en', 'a'}
return [token for token in tokens if token not in stopwords]
def contar_palabras(tokens):
"""Cuenta la frecuencia de cada palabra"""
contador = {}
for token in tokens:
contador[token] = contador.get(token, 0) + 1
return contador
# Componemos las funciones para crear un pipeline de procesamiento de texto
analizar_texto = compose(contar_palabras, eliminar_stopwords, tokenizar, normalizar_texto)
# Analizamos un texto
texto = "El análisis de texto es una técnica importante en el procesamiento del lenguaje natural."
resultado = analizar_texto(texto)
print(resultado)
# {'análisis': 1, 'texto': 1, 'es': 1, 'técnica': 1, 'importante': 1, 'procesamiento': 1, 'del': 1, 'lenguaje': 1, 'natural': 1}
Este ejemplo muestra cómo podemos crear un pipeline de procesamiento de texto completo utilizando compose
, donde cada función realiza una transformación específica y bien definida.
Creación de pipelines de datos
functools.compose
es ideal para crear pipelines de procesamiento de datos, especialmente en análisis de datos y ciencia de datos:
from functools import compose
import statistics
def normalizar_datos(datos):
"""Normaliza los datos restando la media y dividiendo por la desviación estándar"""
media = statistics.mean(datos)
desviacion = statistics.stdev(datos)
return [(x - media) / desviacion for x in datos]
def filtrar_outliers(datos, umbral=2.0):
"""Elimina valores atípicos (outliers)"""
return [x for x in datos if abs(x) <= umbral]
def calcular_estadisticas(datos):
"""Calcula estadísticas básicas de los datos"""
return {
'media': statistics.mean(datos),
'mediana': statistics.median(datos),
'desviacion': statistics.stdev(datos) if len(datos) > 1 else 0,
'min': min(datos),
'max': max(datos)
}
# Creamos un pipeline para procesar datos numéricos
pipeline_estadistico = compose(
calcular_estadisticas,
lambda datos: filtrar_outliers(datos, 1.5), # Usamos lambda para pasar parámetros adicionales
normalizar_datos
)
# Aplicamos el pipeline a un conjunto de datos
datos = [12, 15, 18, 22, 30, 31, 35, 40, 41, 100] # 100 es un outlier
resultado = pipeline_estadistico(datos)
print(resultado)
# Muestra estadísticas de los datos normalizados sin outliers
Limitaciones y consideraciones
Aunque functools.compose
es una herramienta poderosa, tiene algunas limitaciones a tener en cuenta:
- Disponibilidad: Solo está disponible a partir de Python 3.13, por lo que en versiones anteriores necesitarás implementar tu propia función de composición.
- Depuración: Puede ser más difícil depurar errores en funciones compuestas, ya que no es inmediatamente obvio en qué etapa del pipeline ocurrió un error.
- Orden inverso: El orden de aplicación de derecha a izquierda puede resultar confuso para algunos programadores.
Para mitigar estas limitaciones, considera:
from functools import compose
import traceback
def funcion_segura(f):
"""Decorador que captura excepciones y proporciona información de depuración"""
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
print(f"Error en {f.__name__}: {e}")
traceback.print_exc()
raise
return wrapper
# Aplicamos el decorador a nuestras funciones
duplicar_seguro = funcion_segura(lambda x: x * 2)
dividir_seguro = funcion_segura(lambda x: 10 / x)
# Componemos las funciones con manejo de errores
pipeline = compose(duplicar_seguro, dividir_seguro)
try:
resultado = pipeline(0) # Causará un error de división por cero
except:
print("El pipeline falló, pero sabemos dónde")
Alternativa para versiones anteriores de Python
Si estás trabajando con una versión de Python anterior a la 3.13, puedes implementar tu propia versión de compose
:
def compose(*funciones):
"""
Implementación de compose para versiones anteriores de Python.
Compone funciones de derecha a izquierda.
"""
if not funciones:
return lambda x: x # Función identidad
def composicion(x):
resultado = x
for f in reversed(funciones):
resultado = f(resultado)
return resultado
return composicion
# Uso similar a functools.compose
duplicar = lambda x: x * 2
sumar_uno = lambda x: x + 1
f = compose(sumar_uno, duplicar)
resultado = f(5) # 11
print(resultado)
Esta implementación proporciona una funcionalidad similar a functools.compose
y puede usarse como alternativa en versiones anteriores de Python.
Conclusión práctica
functools.compose
representa un paso importante en la evolución de Python hacia un mejor soporte para patrones de programación funcional. Al proporcionar una implementación estándar de composición de funciones, Python facilita la creación de código más modular, legible y mantenible, especialmente para operaciones de procesamiento de datos en cadena.
Ejercicios de esta lección Composición de funciones
Evalúa tus conocimientos de esta lección Composición de funciones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Módulo math
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
Todas las lecciones de Python
Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Python
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el concepto y principios de la composición funcional.
- Aprender a implementar composición de funciones en Python de diversas formas.
- Conocer las ventajas de usar funciones puras y composición para mejorar modularidad y legibilidad.
- Utilizar functools.compose para simplificar la composición a partir de Python 3.13.
- Aplicar composición funcional en ejemplos prácticos de procesamiento de datos y texto.