Función map() de Python: Transforma Iterables con Ejemplos
Updated on
Transformar cada elemento de una lista es una de las operaciones más comunes en la programación con Python. Tienes una lista de cadenas que necesitan convertirse en enteros. Una columna de precios que debe redondearse. Un conjunto de nombres de archivo que deben convertirse a minúsculas. El instinto es escribir un bucle for, crear una lista vacía, agregar cada resultado y devolver la lista. Funciona, pero es verboso, propenso a errores y entierra la lógica de transformación real dentro de código repetitivo.
La función incorporada map() de Python elimina este código repetitivo. Toma una función y uno o más iterables, aplica la función a cada elemento y devuelve un iterador de resultados. Una línea reemplaza cinco. El código se lee como una descripción de lo que quieres, no cómo hacerlo.
Esta guía cubre cada aspecto práctico de la función map de Python: la sintaxis básica, combinar map con lambda y funciones incorporadas, trabajar con múltiples iterables, comparaciones de rendimiento contra list comprehensions y patrones de procesamiento de datos del mundo real que usarás en código de producción.
Sintaxis Básica de map()
La firma de la función map() es directa:
map(function, iterable, *iterables)- function -- un callable que acepta un argumento (o más, si pasas múltiples iterables).
- iterable -- la secuencia cuyos elementos serán pasados a
function. - *iterables -- iterables adicionales opcionales. Cuando se proporcionan,
functiondebe aceptar esa cantidad de argumentos.
map() devuelve un objeto map, que es un iterador perezoso. No calcula todos los resultados inmediatamente. En cambio, produce valores uno a la vez mientras los consumes.
Aquí está el ejemplo más simple posible:
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)
print(squared)
# <map object at 0x...>
print(list(squared))
# [1, 4, 9, 16, 25]El objeto map no muestra resultados directamente. Lo conviertes a una lista, tupla u otra colección, o iteras sobre él en un bucle.
map() con Funciones Incorporadas
Uno de los usos más limpios de map() es combinarlo con las funciones incorporadas de Python. Sin necesidad de lambda -- solo pasa el nombre de la función directamente.
Conversión de Tipos con int, float, str
# Convertir cadenas a enteros
string_numbers = ["10", "20", "30", "40"]
integers = list(map(int, string_numbers))
print(integers)
# [10, 20, 30, 40]
# Convertir enteros a flotantes
values = [1, 2, 3, 4]
floats = list(map(float, values))
print(floats)
# [1.0, 2.0, 3.0, 4.0]
# Convertir números a cadenas
ids = [101, 102, 103]
string_ids = list(map(str, ids))
print(string_ids)
# ['101', '102', '103']Obtener Longitudes con len
words = ["Python", "map", "function", "tutorial"]
lengths = list(map(len, words))
print(lengths)
# [6, 3, 8, 8]Eliminar Espacios con str.strip
raw_inputs = [" hello ", " world ", " python "]
cleaned = list(map(str.strip, raw_inputs))
print(cleaned)
# ['hello', 'world', 'python']Otras Combinaciones Útiles con Funciones Incorporadas
# abs() para valores absolutos
numbers = [-5, 3, -1, 7, -2]
absolutes = list(map(abs, numbers))
print(absolutes)
# [5, 3, 1, 7, 2]
# round() para redondear (forma de un argumento)
prices = [19.995, 4.123, 99.876]
rounded = list(map(round, prices))
print(rounded)
# [20, 4, 100]
# bool() para veracidad
values = [0, 1, "", "hello", None, [], [1]]
truthy = list(map(bool, values))
print(truthy)
# [False, True, False, True, False, False, True]Cuando una función incorporada ya hace lo que necesitas, pásala directamente a map(). No hay razón para envolverla en un lambda.
map() con Funciones Lambda
Las funciones lambda desbloquean todo el poder de map(). Te permiten definir transformaciones en línea sin crear una función con nombre.
# Elevar al cuadrado cada número
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)
# [1, 4, 9, 16, 25]
# Celsius a Fahrenheit
celsius = [0, 20, 37, 100]
fahrenheit = list(map(lambda c: round(c * 9/5 + 32, 1), celsius))
print(fahrenheit)
# [32.0, 68.0, 98.6, 212.0]
# Extraer dominio de direcciones de correo electrónico
emails = ["alice@gmail.com", "bob@company.org", "carol@university.edu"]
domains = list(map(lambda e: e.split("@")[1], emails))
print(domains)
# ['gmail.com', 'company.org', 'university.edu']
# Formatear nombres
names = ["alice smith", "bob jones", "carol white"]
formatted = list(map(lambda n: n.title(), names))
print(formatted)
# ['Alice Smith', 'Bob Jones', 'Carol White']El patrón es consistente: map(lambda x: transform(x), iterable). Mantén el cuerpo del lambda como una expresión única y clara. Si la transformación requiere múltiples pasos, usa una función con nombre en su lugar.
map() con Múltiples Iterables
Cuando pasas múltiples iterables, map() llama a la función con un elemento de cada iterable en paralelo. La función debe aceptar tantos argumentos como iterables haya. La iteración se detiene cuando el iterable más corto se agota.
# Sumar elementos correspondientes de dos listas
list_a = [1, 2, 3, 4]
list_b = [10, 20, 30, 40]
sums = list(map(lambda a, b: a + b, list_a, list_b))
print(sums)
# [11, 22, 33, 44]
# Calcular puntuaciones ponderadas
scores = [85, 92, 78, 95]
weights = [0.3, 0.3, 0.2, 0.2]
weighted = list(map(lambda s, w: round(s * w, 1), scores, weights))
print(weighted)
# [25.5, 27.6, 15.6, 19.0]
# Combinar nombres y apellidos
first_names = ["Ada", "Grace", "Alan"]
last_names = ["Lovelace", "Hopper", "Turing"]
full_names = list(map(lambda f, l: f"{f} {l}", first_names, last_names))
print(full_names)
# ['Ada Lovelace', 'Grace Hopper', 'Alan Turing']Tres o Más Iterables
# Calcular volumen a partir de tres listas de dimensiones
lengths = [2, 3, 4]
widths = [5, 6, 7]
heights = [8, 9, 10]
volumes = list(map(lambda l, w, h: l * w * h, lengths, widths, heights))
print(volumes)
# [80, 162, 280]Manejo de Longitudes Desiguales
map() se detiene en el iterable más corto. Sin error, sin relleno -- simplemente se detiene:
a = [1, 2, 3, 4, 5]
b = [10, 20, 30]
result = list(map(lambda x, y: x + y, a, b))
print(result)
# [11, 22, 33]
# Los elementos 4 y 5 de 'a' se descartan silenciosamenteSi necesitas manejar longitudes desiguales explícitamente, usa itertools.zip_longest:
from itertools import zip_longest
a = [1, 2, 3, 4, 5]
b = [10, 20, 30]
result = list(map(lambda pair: pair[0] + (pair[1] or 0), zip_longest(a, b, fillvalue=0)))
print(result)
# [11, 22, 33, 4, 5]map() vs List Comprehension
Esta es la comparación más importante. Tanto map() como las list comprehensions transforman secuencias, pero tienen diferentes fortalezas.
| Característica | map() | List Comprehension |
|---|---|---|
| Sintaxis | map(func, iterable) | [func(x) for x in iterable] |
| Legibilidad (transformación simple) | Alta con funciones incorporadas | Alta para todos los casos |
| Legibilidad (transformación compleja) | Menor (lambdas anidados) | Mayor (multilínea posible) |
| Soporte de filtrado | No (necesita filter() por separado) | Sí (cláusula if incorporada) |
| Tipo de retorno | Iterador perezoso (objeto map) | Lista inmediata |
| Memoria para datos grandes | Baja (evaluación perezosa) | Alta (lista completa en memoria) |
| Velocidad (función incorporada) | Más rápido (sin llamada a nivel Python) | Ligeramente más lento |
| Velocidad (función lambda) | Comparable | Comparable o ligeramente más rápido |
| Transformaciones anidadas | Incómodo de encadenar | Natural con anidamiento |
| Depuración | Más difícil (perezoso, sin lista intermedia) | Más fácil (resultados inmediatos) |
Benchmark de Rendimiento
import timeit
data = list(range(100_000))
# map con función incorporada
time_map_builtin = timeit.timeit(
'list(map(str, data))',
globals={'data': data},
number=100
)
# List comprehension con función incorporada
time_comp_builtin = timeit.timeit(
'[str(x) for x in data]',
globals={'data': data},
number=100
)
# map con lambda
time_map_lambda = timeit.timeit(
'list(map(lambda x: x * 2, data))',
globals={'data': data},
number=100
)
# List comprehension equivalente
time_comp_expr = timeit.timeit(
'[x * 2 for x in data]',
globals={'data': data},
number=100
)
print(f"map + incorporada: {time_map_builtin:.4f}s")
print(f"comprehension: {time_comp_builtin:.4f}s")
print(f"map + lambda: {time_map_lambda:.4f}s")
print(f"comprehension: {time_comp_expr:.4f}s")
# Resultados típicos:
# map + incorporada: ~0.85s (más rápido)
# comprehension: ~1.05s
# map + lambda: ~0.95s
# comprehension: ~0.80s (más rápido)La idea clave: map() con una función incorporada (como int, str, float) es más rápido porque evita crear una llamada a función a nivel Python en cada iteración. Pero map() con un lambda es aproximadamente la misma velocidad que -- o ligeramente más lento que -- una list comprehension, porque ambos involucran una llamada a función a nivel Python por elemento.
map() vs Expresión Generadora
Si no necesitas la lista completa de resultados en memoria, tanto map() como las expresiones generadoras proporcionan evaluación perezosa:
# Objeto map - perezoso
mapped = map(lambda x: x ** 2, range(1_000_000))
# Expresión generadora - perezosa
generated = (x ** 2 for x in range(1_000_000))
# Ambos consumen memoria solo mientras iteras
for value in mapped:
if value > 100:
breakLa diferencia es estilística. Las expresiones generadoras se leen más naturalmente para la mayoría de desarrolladores Python y soportan filtrado con cláusulas if. Usa map() cuando ya tengas una función con nombre para aplicar; usa una expresión generadora en caso contrario.
# map es limpio cuando tienes una función con nombre
import math
roots = map(math.sqrt, range(10))
# Generador es limpio para expresiones
roots = (x ** 0.5 for x in range(10))Convertir Objetos map a list, tuple y set
El objeto map es un iterador. Para materializar los resultados, conviértelo explícitamente:
numbers = [1, 2, 3, 2, 4, 3, 5]
# A lista (preserva orden, permite duplicados)
as_list = list(map(lambda x: x * 10, numbers))
print(as_list)
# [10, 20, 30, 20, 40, 30, 50]
# A tupla (secuencia inmutable)
as_tuple = tuple(map(lambda x: x * 10, numbers))
print(as_tuple)
# (10, 20, 30, 20, 40, 30, 50)
# A set (elimina duplicados, sin orden)
as_set = set(map(lambda x: x * 10, numbers))
print(as_set)
# {10, 20, 30, 40, 50}Importante: Un objeto map solo puede consumirse una vez. Después de convertirlo a lista, iterar de nuevo no produce nada:
mapped = map(str, [1, 2, 3])
first = list(mapped)
second = list(mapped)
print(first) # ['1', '2', '3']
print(second) # [] -- ya agotadomap() con Funciones Personalizadas
Para transformaciones demasiado complejas para un lambda, define una función regular y pásala a map():
def parse_temperature(reading):
"""Convierte una cadena de lectura de temperatura a un dict estandarizado."""
value, unit = float(reading[:-1]), reading[-1]
if unit == 'F':
celsius = round((value - 32) * 5 / 9, 1)
elif unit == 'C':
celsius = value
elif unit == 'K':
celsius = round(value - 273.15, 1)
else:
raise ValueError(f"Unidad desconocida: {unit}")
return {"original": reading, "celsius": celsius}
readings = ["98.6F", "37.0C", "310.0K", "72.0F"]
parsed = list(map(parse_temperature, readings))
for entry in parsed:
print(f"{entry['original']} -> {entry['celsius']}°C")
# 98.6F -> 37.0°C
# 37.0C -> 37.0°C
# 310.0K -> 36.9°C
# 72.0F -> 22.2°CEste patrón mantiene las llamadas a map() limpias mientras mueve la lógica compleja a funciones testeables y documentadas.
def normalize_record(record):
"""Estandariza un registro de usuario para inserción en base de datos."""
return {
"name": record["name"].strip().title(),
"email": record["email"].strip().lower(),
"age": int(record["age"]),
"active": record.get("active", True),
}
raw_records = [
{"name": " alice smith ", "email": "ALICE@Email.COM", "age": "30"},
{"name": "bob jones", "email": "Bob@Work.ORG ", "age": "25"},
]
clean_records = list(map(normalize_record, raw_records))
for r in clean_records:
print(r)
# {'name': 'Alice Smith', 'email': 'alice@email.com', 'age': 30, 'active': True}
# {'name': 'Bob Jones', 'email': 'bob@work.org', 'age': 25, 'active': True}Encadenar Llamadas a map()
Como map() devuelve un iterador, puedes encadenar múltiples llamadas a map() para construir pipelines de transformación. Cada paso procesa un elemento a la vez sin crear listas intermedias:
raw_data = [" 42 ", " 17 ", " 89 ", " 3 "]
# Cadena: eliminar espacios -> convertir a int -> duplicar el valor
result = map(str.strip, raw_data)
result = map(int, result)
result = map(lambda x: x * 2, result)
print(list(result))
# [84, 34, 178, 6]Para mayor legibilidad, puedes anidar las llamadas (leer de adentro hacia afuera):
raw_data = [" 42 ", " 17 ", " 89 ", " 3 "]
result = list(map(lambda x: x * 2, map(int, map(str.strip, raw_data))))
print(result)
# [84, 34, 178, 6]La versión anidada es compacta pero más difícil de leer. La versión secuencial es más clara para pipelines de múltiples pasos. Ninguna crea listas intermedias -- los tres objetos map se evalúan perezosamente.
map() en Pipelines de Procesamiento de Datos
El procesamiento de datos del mundo real a menudo involucra leer, limpiar, transformar y agregar datos. map() encaja naturalmente en este patrón.
Procesamiento de Entradas de Log
log_lines = [
"2026-02-10 INFO User logged in",
"2026-02-10 ERROR Database timeout",
"2026-02-10 WARNING Disk space low",
"2026-02-10 INFO File uploaded",
]
def parse_log(line):
parts = line.split(" ", 2)
return {"date": parts[0], "level": parts[1], "message": parts[2]}
parsed = list(map(parse_log, log_lines))
errors = list(filter(lambda entry: entry["level"] == "ERROR", parsed))
print(errors)
# [{'date': '2026-02-10', 'level': 'ERROR', 'message': 'Database timeout'}]Lógica de Renombrado de Archivos por Lotes
import os
filenames = ["Report Q1.PDF", "data export.CSV", "NOTES 2026.TXT"]
def sanitize_filename(name):
base, ext = os.path.splitext(name)
return base.strip().lower().replace(" ", "_") + ext.lower()
cleaned = list(map(sanitize_filename, filenames))
print(cleaned)
# ['report_q1.pdf', 'data_export.csv', 'notes_2026.txt']Pipeline de Datos Numéricos
import math
raw_measurements = ["3.14159", "2.71828", "1.41421", "1.73205"]
# Pipeline: parsear -> elevar al cuadrado -> calcular logaritmo -> redondear a 3 decimales
pipeline = map(lambda x: round(x, 3),
map(math.log,
map(lambda x: x ** 2,
map(float, raw_measurements))))
print(list(pipeline))
# [2.292, 2.003, 0.693, 1.099]Cuándo Usar map() vs List Comprehension: Guía de Decisión
Usa esta referencia rápida para decidir qué herramienta se adapta a tu situación:
Usa map() cuando:
- Estás aplicando una sola función incorporada:
map(int, strings),map(str.strip, lines) - Ya tienes una función con nombre que hace la transformación
- Quieres evaluación perezosa y no necesitas la lista completa en memoria
- Estás pasando múltiples iterables para operaciones elemento por elemento
Usa una list comprehension cuando:
- La transformación es una expresión simple:
[x * 2 for x in numbers] - Necesitas filtrar en el mismo paso:
[x for x in items if x > 0] - La lógica involucra múltiples condiciones u operaciones anidadas
- Quieres el resultado como lista inmediatamente
- La legibilidad importa más que la micro-optimización
Usa una expresión generadora cuando:
- Necesitas evaluación perezosa pero quieres la legibilidad de la sintaxis de comprehension
- El resultado se consumirá solo una vez (pasado a
sum(),max(),join(), etc.)
# map -- más limpio para conversión de tipos
integers = list(map(int, ["1", "2", "3"]))
# List comprehension -- más limpio para transformación + filtro
even_squares = [x ** 2 for x in range(20) if x % 2 == 0]
# Expresión generadora -- más limpio para consumo de un solo paso
total = sum(x ** 2 for x in range(1000))Experimentar con map() en RunCell
Cuando construyes pipelines de transformación de datos con map(), probar cada etapa interactivamente es esencial. Necesitas ver resultados intermedios, verificar casos límite y confirmar que los maps encadenados producen la salida esperada.
RunCell (opens in a new tab) es un agente de IA que se ejecuta directamente dentro de notebooks Jupyter. Entiende el contexto de tu notebook -- las variables, DataFrames e imports ya en memoria -- y te ayuda a construir y depurar pipelines de map() paso a paso:
- Visualizar resultados intermedios. Pide a RunCell que muestre lo que produce cada etapa de un
map()encadenado, sin romper tu pipeline. - Sugerir alternativas vectorizadas. Si estás usando
map()en Series de pandas, RunCell puede recomendar operaciones nativas de pandas que se ejecutan 10-100x más rápido. - Convertir entre map y comprehension. Describe la transformación y RunCell genera ambas versiones para que elijas la más legible.
- Depurar casos límite. Alimenta entradas inesperadas (valores None, cadenas vacías, tipos mixtos) en tu pipeline map y ve exactamente dónde falla.
FAQ
¿Qué hace la función map() en Python?
La función map() aplica una función dada a cada elemento en uno o más iterables (como listas, tuplas o cadenas) y devuelve un iterador de los resultados. Es una función incorporada que permite la transformación de datos al estilo funcional sin escribir bucles explícitos. La sintaxis es map(function, iterable), y el objeto map devuelto es perezoso -- calcula resultados bajo demanda en lugar de todos a la vez.
¿Es map() más rápido que un bucle for en Python?
Sí, map() es generalmente más rápido que un bucle for equivalente que construye una lista con append(). La ventaja de velocidad proviene de que map() está implementado en C a nivel del intérprete, lo que evita la sobrecarga de la iteración de bucle y las llamadas a métodos a nivel Python. Cuando usas map() con una función incorporada como int o str, la ganancia de rendimiento es más significativa -- típicamente 20-40% más rápido. Con un lambda, la diferencia se reduce porque el lambda mismo introduce una llamada a función a nivel Python.
¿Cómo convierto un objeto map a una lista?
Envuelve la llamada a map() con list(): result = list(map(int, strings)). También puedes convertir a otras colecciones: tuple(map(...)) para tuplas, set(map(...)) para sets. Recuerda que un objeto map es un iterador de un solo uso. Una vez consumido (al convertirlo a lista o iterar sobre él), está agotado y no puede reutilizarse.
¿Puede map() trabajar con múltiples listas?
Sí. Pasa múltiples iterables después de la función: map(func, list1, list2, list3). La función debe aceptar el mismo número de argumentos que iterables haya. Por ejemplo, list(map(lambda a, b: a + b, [1, 2], [10, 20])) devuelve [11, 22]. La iteración se detiene en el iterable más corto, por lo que las listas de longitudes desiguales no generan errores -- los elementos extra se ignoran silenciosamente.
¿Debería usar map() o una list comprehension?
Usa map() cuando apliques una sola función existente (incorporada o con nombre) a un iterable, especialmente para conversiones de tipo como map(int, strings). Usa una list comprehension cuando la transformación involucre una expresión, cuando necesites filtrar con una cláusula if, o cuando la legibilidad sea la prioridad. En Python moderno, las list comprehensions son la opción predeterminada para la mayoría de desarrolladores, pero map() con funciones incorporadas sigue siendo más rápido y conciso para transformaciones simples de una función.
Conclusión
La función map() de Python es una herramienta precisa para un trabajo específico: aplicar una sola función a cada elemento de un iterable sin escribir un bucle. Sobresale cuando se combina con funciones incorporadas como int, str, float y len, donde produce el código más legible y rápido. Con funciones lambda, maneja transformaciones en línea de manera limpia. Con múltiples iterables, procesa operaciones elemento por elemento que de otro modo requerirían zip() y un bucle.
Aquí están las reglas para usar map() efectivamente:
- Pasa funciones incorporadas directamente:
map(int, strings)nomap(lambda x: int(x), strings). - Usa lambda solo para transformaciones simples de una sola expresión.
- Cambia a una función con nombre cuando la transformación necesite manejo de errores, múltiples pasos o documentación.
- Prefiere list comprehensions cuando necesites filtrar o cuando la expresión sea más clara en línea.
- Recuerda que
map()devuelve un iterador perezoso de un solo uso -- convierte alist()cuando necesites reutilizar o inspeccionar resultados. - Encadena llamadas a
map()para pipelines de múltiples pasos sin crear listas intermedias.
map() no es un reemplazo para list comprehensions, y las list comprehensions no son un reemplazo para map(). Se superponen pero sirven a diferentes fortalezas. El mejor código Python usa cada uno donde encaja naturalmente: map() para aplicar funciones existentes, list comprehensions para expresiones y filtrado, y expresiones generadoras para consumo perezoso de un solo paso.