map() y filter() son funciones de orden superior de Python 3 que devuelven iteradores. Son la forma funcional de transformar y filtrar iterables, aunque en la práctica la comunidad Python prefiere las list comprehensions en la mayoría de los casos.
map(): transformar cada elemento
# map(función, iterable) devuelve un iterador numeros = [1, 2, 3, 4, 5] # Con lambda cuadrados = map(lambda x: x**2, numeros) print(list(cuadrados)) # [1, 4, 9, 16, 25] # Con función con nombre (más eficiente) print(list(map(str, numeros))) # ['1', '2', '3', '4', '5'] print(list(map(abs, [-1, 2, -3, 4]))) # [1, 2, 3, 4] # map con múltiples iterables a = [1, 2, 3] b = [10, 20, 30] print(list(map(lambda x, y: x + y, a, b))) # [11, 22, 33] # Se para en el más corto
filter(): filtrar según una condición
numeros = range(-5, 6) # filter(función, iterable) la función devuelve True/False positivos = filter(lambda x: x > 0, numeros) print(list(positivos)) # [1, 2, 3, 4, 5] # filter(None, iterable) elimina valores falsy con_vacios = ["hola", "", None, "mundo", 0, "python"] no_vacios = list(filter(None, con_vacios)) print(no_vacios) # ['hola', 'mundo', 'python']
map vs list comprehension
numeros = [1, 2, 3, 4, 5]
# Con map + lambda
cuadrados_map = list(map(lambda x: x**2, numeros))
# Con list comprehension (más legible, preferida en Python)
cuadrados_comp = [x**2 for x in numeros]
# Con map + función con nombre (comparable en legibilidad)
def cuadrado(x):
return x**2
cuadrados_fn = list(map(cuadrado, numeros))
# Los tres producen el mismo resultado
# La PEP 8 y Guido van Rossum prefieren comprehensions cuando se usa lambda
# map() con función con nombre es aceptable y puede ser más rápido
filter vs list comprehension
numeros = range(20)
# filter + lambda
pares_filter = list(filter(lambda x: x % 2 == 0, numeros))
# comprehension (más clara)
pares_comp = [x for x in numeros if x % 2 == 0]
# Para condiciones complejas, la comprehension gana en legibilidad:
usuarios = [{"nombre": "Ana", "activo": True, "edad": 28},
{"nombre": "Luis", "activo": False, "edad": 34}]
activos = [u for u in usuarios if u["activo"] and u["edad"] >= 18]
# vs
activos = list(filter(lambda u: u["activo"] and u["edad"] >= 18, usuarios))
Encadenar map y filter
datos = [" Python ", "", " Rust ", " ", "Go"]
# Cadena de transformaciones con map y filter
# (sin crear listas intermedias eficiente en memoria)
resultado = list(
map(str.upper,
filter(None,
map(str.strip, datos)))
)
print(resultado) # ['PYTHON', 'RUST', 'GO']
# La misma lógica con comprehension (más legible)
resultado = [s.strip().upper() for s in datos if s.strip()]
Cuándo usar map() o filter()
# USA map() cuando: # - Ya tienes una función con nombre (sin necesidad de lambda) # - Trabajas con múltiples iterables en paralelo print(list(map(int, ["1", "2", "3"]))) # map + función existente # USA filter() con None para eliminar falsy en una línea print(list(filter(None, [0, 1, "", "ok", None, True]))) # USA comprehensions cuando la lógica involucra lambda # o cuando la legibilidad importa más que un micro-benchmark # En pipelines de datos con muchos pasos, map y filter # evitan crear listas intermedias: pipeline = filter(lambda x: x > 0, map(int, ["1", "-2", "3", "-4"])) print(list(pipeline)) # [1, 3]
La guía de estilo de Python prefiere las comprehensions sobre map()/filter() con lambdas, pero map() con funciones ya definidas es perfectamente idiomático. La diferencia de rendimiento suele ser insignificante; elige en función de la legibilidad.
