Programación funcional en Python: map, filter y reduce

D
DanisCh
(Actualizado: ) 4 min de lectura
Programación funcional en Python: map, filter y reduce
Python

Python no es un lenguaje funcional puro, pero incorpora herramientas que permiten escribir código siguiendo este paradigma. Tres de las más conocidas son map(), filter() y reduce(), funciones de orden superior que reciben otras funciones como argumento y permiten transformar, seleccionar y combinar datos sin necesidad de bucles explícitos.

¿Qué es la programación funcional?

La programación funcional es un paradigma que trata la computación como la evaluación de funciones matemáticas, evitando el cambio de estado y los datos mutables. Sus principios clave incluyen:

  • Funciones puras: dado el mismo input, siempre devuelven el mismo output, sin efectos secundarios.
  • Inmutabilidad: los datos no se modifican, se generan nuevas versiones.
  • Funciones como ciudadanos de primera clase: pueden pasarse como argumentos, devolverse y almacenarse en variables.

map(): transformar elementos

map() aplica una función a cada elemento de un iterable y devuelve un nuevo iterador con los resultados. Su sintaxis es:

map(funcion, iterable)

Ejemplo básico

numeros = [1, 2, 3, 4, 5]
cuadrados = map(lambda x: x ** 2, numeros)
print(list(cuadrados))
# [1, 4, 9, 16, 25]

map() con múltiples iterables

map() puede recibir varios iterables a la vez; la función pasada debe aceptar tantos argumentos como iterables se proporcionen.

precios = [10, 20, 30]
cantidades = [2, 3, 1]
totales = map(lambda p, c: p * c, precios, cantidades)
print(list(totales))
# [20, 60, 30]

filter(): seleccionar elementos

filter() construye un iterador con los elementos de un iterable para los que una función devuelve un valor verdadero. Su sintaxis es:

filter(funcion, iterable)

Ejemplo básico

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pares = filter(lambda x: x % 2 == 0, numeros)
print(list(pares))
# [2, 4, 6, 8, 10]

filter() con None

Si se pasa None como función, filter() elimina los elementos falsy (0, "", None, False, etc.).

valores = [0, 1, "", "hola", None, True, False, 42]
limpios = filter(None, valores)
print(list(limpios))
# [1, 'hola', True, 42]

reduce(): combinar elementos

A diferencia de map() y filter(), reduce() no está disponible directamente; debe importarse del módulo functools. Aplica una función de dos argumentos acumulativamente a los elementos de un iterable, reduciéndolo a un único valor.

from functools import reduce

reduce(funcion, iterable[, valor_inicial])

Ejemplo básico

from functools import reduce

numeros = [1, 2, 3, 4, 5]
suma = reduce(lambda acc, x: acc + x, numeros)
print(suma)
# 15

reduce() con valor inicial

from functools import reduce

numeros = [1, 2, 3, 4]
producto = reduce(lambda acc, x: acc * x, numeros, 10)
print(producto)
# 240  (10 * 1 * 2 * 3 * 4)

Encontrar el máximo con reduce()

from functools import reduce

numeros = [3, 7, 2, 9, 4]
maximo = reduce(lambda a, b: a if a > b else b, numeros)
print(maximo)
# 9

Combinando las tres funciones

Es común encadenar map(), filter() y reduce() para construir pipelines de procesamiento de datos en una sola expresión.

from functools import reduce

numeros = range(1, 21)

resultado = reduce(
    lambda acc, x: acc + x,
    filter(lambda x: x % 2 == 0,
           map(lambda x: x ** 2, numeros))
)

print(resultado)
# Suma de los cuadrados de los números pares del 1 al 20

map/filter/reduce vs. comprensiones de listas

En Python, muchas veces las comprensiones de listas son más legibles y "pythónicas" que map() y filter():

# Con map y filter
resultado = list(filter(lambda x: x % 2 == 0, map(lambda x: x ** 2, numeros)))

# Con comprensión de listas (equivalente)
resultado = [x ** 2 for x in numeros if (x ** 2) % 2 == 0]

Sin embargo, map() y filter() siguen siendo útiles cuando:

  • Ya se tiene una función definida y reutilizable (no una lambda ad hoc).
  • Se trabaja con iteradores perezosos y se quiere evitar crear listas intermedias en memoria.
  • Se prioriza un estilo explícitamente funcional, por ejemplo combinando con itertools.

Para reduce() no existe un equivalente directo con comprensiones, por lo que sigue siendo la herramienta natural para acumular un resultado a partir de una secuencia.

Rendimiento y evaluación perezosa (lazy evaluation)

Tanto map() como filter() devuelven iteradores, no listas. Esto significa que los valores se calculan bajo demanda, lo cual ahorra memoria al trabajar con grandes volúmenes de datos.

numeros = range(1_000_000)
cuadrados = map(lambda x: x ** 2, numeros)  # No calcula nada todavía
print(next(cuadrados))  # Calcula solo el primer elemento: 0

Buenas prácticas

  • Usa funciones con nombre en lugar de lambda cuando la lógica sea compleja o se reutilice.
  • Prefiere comprensiones de listas cuando mejoren la legibilidad.
  • Aprovecha map() y filter() para procesar flujos de datos grandes sin cargarlos todos en memoria.
  • Documenta bien las funciones acumuladoras pasadas a reduce(), ya que su lógica puede no ser evidente a simple vista.

Conclusión

map(), filter() y reduce() son herramientas fundamentales para aplicar un estilo de programación funcional en Python. Permiten transformar, seleccionar y combinar datos de forma declarativa, reduciendo la necesidad de bucles explícitos y favoreciendo un código más conciso. Aunque en muchos casos las comprensiones de listas ofrecen una alternativa más legible, comprender estas tres funciones amplía las posibilidades a la hora de diseñar soluciones, especialmente cuando se trabaja con iteradores, datos masivos o se busca un estilo explícitamente funcional.

¿Te ha gustado esta entrada?

Compártela con tus compañeros para que también sigan aprendiendo.

Comunidad y Comentarios

0 COMENTARIOS

No hay comentarios todavía. Sé el primero en compartir tu opinión.

Escribe tu opinión
Respondiendo a