map() y filter() en Python: guía práctica y eficiente

Publicado el: 11/07/2026
Tempo de leitura: 5 minutos
Uso de map e filter para agilizar código Python

Las funciones map() y filter() forman parte de las herramientas integradas de Python para procesar iterables. map() transforma cada elemento mediante una función, mientras filter() conserva únicamente los elementos que cumplen una condición. Ambas devuelven iteradores perezosos, por lo que pueden trabajar con grandes cantidades de datos sin crear listas intermedias automáticamente.

Para utilizarlas correctamente conviene conocer las funciones en Python, las funciones lambda, los bucles for y las list comprehensions. Aunque map() y filter() pueden producir código elegante, no siempre son la opción más legible.

Cómo funciona map()

map(funcion, iterable) aplica la función a cada valor:

def duplicar(numero):
    return numero * 2

numeros = [1, 2, 3, 4]
resultado = map(duplicar, numeros)

print(resultado)
print(list(resultado))

El resultado inicial es un objeto map, no una lista. Los valores se calculan durante la iteración.

Usar map con lambda

precios = [10, 25, 40]
con_impuesto = map(lambda precio: precio * 1.21, precios)
print(list(con_impuesto))

Una lambda resulta útil cuando la transformación es pequeña y evidente. Si incluye varias operaciones, validaciones o nombres importantes, utiliza una función definida con def.

Map con varias colecciones

map() puede recibir más de un iterable. La función debe aceptar el mismo número de argumentos:

cantidades = [2, 3, 1]
precios = [10.0, 5.5, 20.0]

totales = map(
    lambda cantidad, precio: cantidad * precio,
    cantidades,
    precios
)

print(list(totales))

La iteración termina cuando se agota el iterable más corto. Si necesitas detectar longitudes diferentes, valida antes o utiliza zip(..., strict=True) en versiones recientes de Python.

Cómo funciona filter()

filter(funcion, iterable) conserva los elementos para los que la función devuelve un valor verdadero:

def es_par(numero):
    return numero % 2 == 0

numeros = [1, 2, 3, 4, 5, 6]
pares = filter(es_par, numeros)
print(list(pares))

La función de prueba no necesita devolver literalmente True o False; Python utiliza la verdad lógica del resultado.

Filtrar con lambda

usuarios = [
    {"nombre": "Ana", "activo": True},
    {"nombre": "Luis", "activo": False},
    {"nombre": "Marta", "activo": True},
]

activos = filter(lambda usuario: usuario["activo"], usuarios)
print(list(activos))

Para reglas de negocio complejas, una función con nombre documenta mejor la intención.

Filter con None

valores = [0, 1, "", "Python", None, [], [1]]
limpios = filter(None, valores)
print(list(limpios))

Cuando la función es None, se eliminan todos los valores falsy: cero, cadenas vacías, listas vacías y None. Esto puede borrar valores válidos como cero. Si solo quieres eliminar None, escribe una condición explícita:

limpios = filter(lambda valor: valor is not None, valores)

Encadenar filter y map

numeros = range(1, 20)
pares = filter(lambda n: n % 2 == 0, numeros)
cuadrados = map(lambda n: n ** 2, pares)
print(list(cuadrados))

El pipeline filtra primero y transforma después. Como ambos objetos son perezosos, no se crean listas intermedias.

El orden de las operaciones importa

Si la transformación es costosa, filtrar primero puede ahorrar trabajo:

validos = filter(validar, registros)
procesados = map(transformar, validos)

Sin embargo, algunas condiciones solo pueden evaluarse después de transformar. Diseña el orden según el significado y el coste.

Comparación con list comprehensions

Este código:

resultado = list(
    map(lambda n: n ** 2, filter(lambda n: n % 2 == 0, numeros))
)

Puede escribirse de forma más directa:

resultado = [n ** 2 for n in numeros if n % 2 == 0]

La comprensión suele ser más legible para transformaciones y filtros simples. map() es especialmente expresivo cuando ya existe una función con nombre:

normalizados = map(normalizar_email, correos)

La decisión debe priorizar claridad, no cantidad de caracteres.

Comparación con expresiones generadoras

resultado = (
    n ** 2
    for n in numeros
    if n % 2 == 0
)

La expresión generadora también es perezosa. Para una transformación simple, puede ser más fácil de leer que una cadena de map() y filter().

Consumir el iterador una sola vez

resultado = map(str.upper, ["a", "b", "c"])

print(list(resultado))
print(list(resultado))

La segunda lista queda vacía porque el iterador ya fue consumido. Si necesitas reutilizar los valores, conviértelos en lista una vez o crea nuevamente el pipeline.

Procesar archivos grandes

from pathlib import Path

with Path("eventos.log").open(encoding="utf-8") as archivo:
    lineas = map(str.strip, archivo)
    errores = filter(lambda linea: "ERROR" in linea, lineas)

    for error in errores:
        guardar_error(error)

El archivo se procesa línea por línea. La memoria no depende del tamaño total del registro.

Normalizar datos

def normalizar_nombre(nombre):
    return " ".join(nombre.strip().split()).title()

nombres = ["  ana  silva ", "LUIS perez", " marta"]
normalizados = list(map(normalizar_nombre, nombres))

Una función con nombre facilita pruebas y reutilización.

Filtrar registros inválidos

def registro_valido(registro):
    return (
        registro.get("id") is not None
        and registro.get("email")
        and registro.get("activo") is True
    )

validos = filter(registro_valido, registros)

Evita acceder directamente a claves que pueden faltar si los datos proceden de una fuente externa.

Manejo de errores dentro de map

Si la función lanza una excepción, la iteración se detiene:

def convertir_entero(texto):
    try:
        return int(texto)
    except (TypeError, ValueError):
        return None

valores = map(convertir_entero, ["10", "x", "25"])
validos = filter(lambda valor: valor is not None, valores)
print(list(validos))

En procesos donde necesitas conocer los errores, devuelve una estructura con estado en lugar de perder silenciosamente el valor original.

Usar funciones de la biblioteca estándar

import math

numeros = [1, 4, 9, 16]
raices = map(math.sqrt, numeros)
print(list(raices))

map() funciona muy bien con funciones existentes como str.strip, str.lower, abs o math.sqrt.

Documentación oficial

La referencia oficial de map() explica la aplicación sobre uno o varios iterables. La referencia oficial de filter() describe el comportamiento con una función o con None.

Rendimiento y memoria

Como map() y filter() son perezosos, pueden ahorrar memoria. Esto no significa que siempre sean más rápidos. Las comprensiones están muy optimizadas y pueden ser igual o más rápidas para expresiones sencillas. Mide con timeit usando datos representativos.

El mayor beneficio suele ser evitar una lista intermedia cuando el consumidor acepta un iterable, por ejemplo sum(), any(), all(), un bucle o una escritura progresiva.

Cuándo evitar map y filter

Evítalos cuando la lambda sea difícil de entender, cuando haya varias condiciones anidadas, cuando necesites manejo de errores detallado o cuando el proceso tenga efectos secundarios. Un bucle explícito es mejor para registrar, actualizar varios objetos o controlar break y continue.

Errores frecuentes

Los problemas más comunes son olvidar convertir el iterador al mostrarlo, intentar recorrerlo varias veces, usar filter(None, ...) y perder ceros válidos, encadenar lambdas ilegibles y asumir que la pereza garantiza mayor velocidad. También debes recordar que una excepción puede aparecer durante el consumo, no al crear el objeto.

Conclusión

map() transforma elementos y filter() selecciona valores. Ambas funciones son perezosas y permiten crear pipelines sin listas intermedias. Son especialmente claras cuando reciben funciones con nombres descriptivos. Para expresiones cortas, las comprensiones y expresiones generadoras suelen ser más legibles. La mejor elección es la que comunica la intención, maneja los errores correctamente y se adapta al patrón de consumo de los datos.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Pattern matching com match case em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    match-case en Python: guía de pattern matching

    Aprende match-case en Python: patrones con valores, listas, diccionarios, dataclasses, guards, capturas, constantes y ejemplos prácticos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Comparação entre list comprehension e generator expression em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    List comprehension vs generator expression en Python

    Compara list comprehension y generator expression en Python: memoria, evaluación perezosa, rendimiento, reutilización y casos prácticos.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Logo do Python com as palavras global e local
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Alcance de variables en Python: entiende la regla LEGB

    Entiende el alcance de variables en Python con la regla LEGB, global, nonlocal, closures, sombreado, mutabilidad y UnboundLocalError.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Operações matemáticas usando o módulo math em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo math en Python: operaciones matemáticas esenciales

    Aprende el módulo math en Python: raíces, potencias, redondeos, trigonometría, logaritmos, constantes, isclose y ejemplos prácticos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Geração de números aleatórios seguros usando secrets em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Módulo secrets en Python: números y tokens seguros

    Aprende secrets en Python para generar contraseñas, códigos y tokens seguros con randbelow, choice, token_hex, token_urlsafe y compare_digest.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Uso do operador walrus para atribuições inline em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Operador walrus en Python: guía con ejemplos

    Aprende el operador walrus := en Python: condiciones, while, comprensiones, lectura por bloques, regex, alcance y buenas prácticas.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026