map() y filter(): transforma y filtra iterables

Actualizado el: 20/08/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

    notebook com código saindo da tela
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Variables: asignación, tipos y alcance en Python

    Aprende variables en Python: asignación, nombres, tipos, conversiones, referencias, mutabilidad, alcance, constantes, None y errores frecuentes.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Diferença entre operadores is e == em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    == vs is en Python: igualdad vs identidad

    Entiende la diferencia entre == e is en Python, igualdad, identidad, None, interning, copias superficiales, deepcopy y objetos personalizados.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Menu interativo no terminal criado com Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    Menú interactivo en terminal con Python

    Crea un menú interactivo en Python con while, funciones, diccionarios, validación, submenús, persistencia JSON y manejo seguro de errores.

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    ícone de loop com o texto 'While' abaixo
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    while: repite acciones con condiciones en Python

    Aprende bucles while en Python con condiciones, validación, menús, break, continue, else, centinelas, reintentos y buenas prácticas.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Imagem de um quadro negro com várias interrogações no lugar de lâmpadas, e uma lâmpada conectada no meio
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    if, elif y else: lógica condicional en Python

    Aprende if, elif y else en Python con comparaciones, operadores lógicos, validación, rangos, menús, retornos tempranos y pruebas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Manipulação de dados JSON em Python
    Fundamentos
    Foto de perfil de Leandro Hirt da Academify

    JSON en Python: leer, escribir y validar datos

    Aprende JSON en Python con load, loads, dump, dumps, archivos UTF-8, validación, APIs, Decimal, fechas y escritura segura.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026