Python

Python

Tutorial Python: Funciones orden superior map y filter

Aprende a usar las funciones map y filter en Python para transformar y filtrar datos con ejemplos prácticos y comparativas con comprehensions.

Aprende Python y certifícate

Map

La función map es una herramienta fundamental en la programación funcional con Python que permite aplicar una función a cada elemento de un iterable (como listas, tuplas o conjuntos) y devolver un nuevo iterable con los resultados. Esta función representa un enfoque declarativo para transformar datos, centrándonos en el "qué" queremos lograr en lugar del "cómo" lograrlo.

La sintaxis básica de map es:

map(función, iterable, [iterable2, iterable3, ...])

Donde:

  • función es la operación que se aplicará a cada elemento
  • iterable es la colección de datos a procesar
  • Opcionalmente, se pueden pasar múltiples iterables si la función acepta múltiples argumentos

Características principales de map

La función map tiene varias características que la hacen especialmente útil:

  • Devuelve un objeto iterable de tipo map que puede convertirse a otros tipos de colecciones
  • Es perezosa (lazy evaluation), lo que significa que no procesa los elementos hasta que se consumen
  • No modifica la colección original, siguiendo los principios de la programación funcional
  • Puede trabajar con cualquier tipo de función: nombradas, lambda o métodos

Uso básico de map

Veamos un ejemplo simple donde aplicamos una función a cada elemento de una lista:

# Convertir una lista de temperaturas de Celsius a Fahrenheit
celsius = [0, 10, 20, 30, 40]

# Definimos la función de conversión
def celsius_a_fahrenheit(c):
    return (c * 9/5) + 32

# Aplicamos map
fahrenheit = map(celsius_a_fahrenheit, celsius)

# Convertimos el resultado a lista para visualizarlo
print(list(fahrenheit))  # [32.0, 50.0, 68.0, 86.0, 104.0]

También podemos usar una función lambda para hacer el código más conciso:

celsius = [0, 10, 20, 30, 40]
fahrenheit = map(lambda c: (c * 9/5) + 32, celsius)
print(list(fahrenheit))  # [32.0, 50.0, 68.0, 86.0, 104.0]

Trabajando con el objeto map

Es importante entender que map() devuelve un objeto iterable que se consume al recorrerlo:

numeros = [1, 2, 3, 4, 5]
cuadrados = map(lambda x: x**2, numeros)

# El objeto map se puede iterar
for cuadrado in cuadrados:
    print(cuadrado)  # Imprime 1, 4, 9, 16, 25

# Intentar iterar nuevamente no produce resultados
print(list(cuadrados))  # []

Si necesitas usar los resultados múltiples veces, debes convertir el objeto map a una estructura de datos como lista o tupla:

numeros = [1, 2, 3, 4, 5]
cuadrados = list(map(lambda x: x**2, numeros))

# Ahora podemos usar cuadrados múltiples veces
print(cuadrados)  # [1, 4, 9, 16, 25]
print(cuadrados[0])  # 1

Map con múltiples iterables

Una característica poderosa de map es su capacidad para trabajar con múltiples iterables simultáneamente:

# Sumar elementos correspondientes de dos listas
lista1 = [1, 2, 3, 4]
lista2 = [10, 20, 30, 40]

sumas = map(lambda x, y: x + y, lista1, lista2)
print(list(sumas))  # [11, 22, 33, 44]

Si los iterables tienen diferentes longitudes, map se detendrá cuando llegue al final del iterable más corto:

numeros = [1, 2, 3, 4, 5]
potencias = [2, 3]  # Solo dos elementos

resultados = map(lambda x, y: x**y, numeros, potencias)
print(list(resultados))  # [1, 8] - Solo procesa los dos primeros elementos

Map con funciones de la biblioteca estándar

Podemos usar map con funciones incorporadas de Python:

# Convertir una lista de cadenas a enteros
numeros_str = ["1", "2", "3", "4", "5"]
numeros_int = map(int, numeros_str)
print(list(numeros_int))  # [1, 2, 3, 4, 5]

# Obtener la longitud de cada cadena en una lista
palabras = ["Python", "es", "genial"]
longitudes = map(len, palabras)
print(list(longitudes))  # [6, 2, 6]

Map con métodos de objetos

También podemos usar map con métodos de objetos:

# Convertir todas las cadenas a mayúsculas
nombres = ["ana", "juan", "maría", "pedro"]
nombres_mayusculas = map(str.upper, nombres)
print(list(nombres_mayusculas))  # ['ANA', 'JUAN', 'MARÍA', 'PEDRO']

# Eliminar espacios en blanco al inicio y final de cada cadena
textos = ["  hola  ", " mundo ", "  python  "]
textos_limpios = map(str.strip, textos)
print(list(textos_limpios))  # ['hola', 'mundo', 'python']

Casos de uso prácticos

La función map es especialmente útil en escenarios como:

  • Procesamiento de datos: transformar valores en un conjunto de datos
# Redondear todos los valores en una lista de mediciones
mediciones = [12.3456, 23.4567, 34.5678, 45.6789]
redondeados = map(lambda x: round(x, 2), mediciones)
print(list(redondeados))  # [12.35, 23.46, 34.57, 45.68]
  • Conversión de tipos: cambiar el tipo de datos de elementos en una colección
# Convertir una lista mixta a sus representaciones de cadena
datos = [10, 3.14, True, "Python"]
cadenas = map(str, datos)
print(list(cadenas))  # ['10', '3.14', 'True', 'Python']
  • Aplicación de fórmulas: calcular nuevos valores basados en datos existentes
# Calcular el área de varios círculos a partir de sus radios
import math
radios = [1, 2, 3, 4, 5]
areas = map(lambda r: math.pi * r**2, radios)
print(list(areas))  # [3.141592653589793, 12.566370614359172, 28.274333882308138, 50.26548245743669, 78.53981633974483]

Rendimiento y consideraciones

La función map es generalmente más eficiente que los bucles equivalentes para operaciones simples, especialmente cuando se trabaja con grandes conjuntos de datos. Esto se debe a que:

  • Está implementada en C, lo que la hace más rápida que el código Python puro
  • Utiliza evaluación perezosa, procesando elementos solo cuando se necesitan
  • Reduce la sobrecarga de las llamadas a funciones Python

Sin embargo, para operaciones muy complejas o cuando la legibilidad es prioritaria, las comprensiones de listas pueden ser una mejor opción.

# Comparación de rendimiento (conceptual)
import time

numeros = list(range(1000000))

# Usando map
inicio = time.time()
cuadrados_map = list(map(lambda x: x**2, numeros))
fin = time.time()
print(f"Tiempo con map: {fin - inicio} segundos")

# Usando un bucle for
inicio = time.time()
cuadrados_for = []
for n in numeros:
    cuadrados_for.append(n**2)
fin = time.time()
print(f"Tiempo con for: {fin - inicio} segundos")

Integración con otras funciones funcionales

La función map se combina perfectamente con otras funciones de programación funcional como filter y reduce:

from functools import reduce

# Calcular la suma de los cuadrados de los números pares
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Primero filtramos los números pares
pares = filter(lambda x: x % 2 == 0, numeros)

# Luego calculamos sus cuadrados
cuadrados = map(lambda x: x**2, pares)

# Finalmente sumamos todos los cuadrados
suma = reduce(lambda x, y: x + y, cuadrados)

print(suma)  # 220 (4 + 16 + 36 + 64 + 100)

Este enfoque de encadenamiento de operaciones es muy común en la programación funcional y permite crear flujos de procesamiento de datos elegantes y expresivos.

Filter

La función filter es una herramienta esencial en la programación funcional de Python que permite seleccionar elementos de un iterable basándose en una función de prueba. A diferencia de map que transforma cada elemento, filter decide qué elementos conservar en el resultado final, eliminando aquellos que no cumplen con un criterio específico.

La sintaxis básica de filter es:

filter(función, iterable)

Donde:

  • función es un predicado (función que devuelve un valor booleano) que determina si un elemento debe incluirse
  • iterable es la colección de datos a filtrar

Características principales de filter

La función filter presenta varias características importantes:

  • Devuelve un objeto iterable de tipo filter que contiene solo los elementos que pasan la prueba
  • Implementa evaluación perezosa, procesando elementos solo cuando se consumen
  • Preserva la colección original, siguiendo los principios de inmutabilidad
  • Acepta None como función, lo que filtra elementos que evalúan a False en un contexto booleano

Uso básico de filter

Veamos un ejemplo simple donde filtramos números pares de una lista:

# Filtrar números pares de una lista
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Definimos la función de filtrado
def es_par(numero):
    return numero % 2 == 0

# Aplicamos filter
pares = filter(es_par, numeros)

# Convertimos el resultado a lista para visualizarlo
print(list(pares))  # [2, 4, 6, 8, 10]

Al igual que con map, podemos usar una función lambda para hacer el código más conciso:

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]

Trabajando con el objeto filter

Es importante entender que filter() devuelve un objeto iterable que se consume al recorrerlo:

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

# El objeto filter se puede iterar
for par in pares:
    print(par)  # Imprime 2, 4, 6, 8, 10

# Intentar iterar nuevamente no produce resultados
print(list(pares))  # []

Si necesitas usar los resultados múltiples veces, debes convertir el objeto filter a una estructura de datos como lista o tupla:

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

# Ahora podemos usar pares múltiples veces
print(pares)  # [2, 4, 6, 8, 10]
print(pares[0])  # 2

Usando None como función de filtrado

Una característica interesante de filter es que podemos pasar None como función, lo que filtrará elementos que evalúan a False en un contexto booleano:

# Filtrar valores "falsy" (0, None, False, "", [], {}, etc.)
valores_mixtos = [0, 1, False, True, "", "texto", [], [1, 2], None, 42]
valores_truthy = filter(None, valores_mixtos)
print(list(valores_truthy))  # [1, True, 'texto', [1, 2], 42]

Esto es útil para eliminar rápidamente valores vacíos o nulos de una colección.

Filtrando diferentes tipos de datos

La función filter puede trabajar con cualquier tipo de iterable y cualquier tipo de datos:

Filtrando cadenas

# Filtrar palabras que comienzan con 'p'
palabras = ["python", "programación", "código", "desarrollo", "prueba"]
palabras_con_p = filter(lambda palabra: palabra.startswith('p'), palabras)
print(list(palabras_con_p))  # ['python', 'programación', 'prueba']

Filtrando diccionarios

# Filtrar productos con precio mayor a 50
productos = [
    {"nombre": "Teclado", "precio": 45},
    {"nombre": "Monitor", "precio": 200},
    {"nombre": "Ratón", "precio": 25},
    {"nombre": "Disco SSD", "precio": 80}
]

productos_caros = filter(lambda producto: producto["precio"] > 50, productos)
print(list(productos_caros))  
# [{'nombre': 'Monitor', 'precio': 200}, {'nombre': 'Disco SSD', 'precio': 80}]

Filtrando objetos personalizados

class Estudiante:
    def __init__(self, nombre, calificacion):
        self.nombre = nombre
        self.calificacion = calificacion
    
    def __repr__(self):
        return f"Estudiante({self.nombre}, {self.calificacion})"

estudiantes = [
    Estudiante("Ana", 85),
    Estudiante("Juan", 70),
    Estudiante("María", 92),
    Estudiante("Pedro", 65)
]

# Filtrar estudiantes con calificación >= 80 (aprobados con distinción)
aprobados_distincion = filter(lambda e: e.calificacion >= 80, estudiantes)
print(list(aprobados_distincion))  
# [Estudiante(Ana, 85), Estudiante(María, 92)]

Casos de uso prácticos

La función filter es especialmente útil en escenarios como:

  • Limpieza de datos: eliminar valores no deseados o inválidos
# Eliminar valores nulos o vacíos de una lista de datos
datos = ["valor1", None, "", "valor2", 0, "valor3", [], {}]
datos_limpios = filter(bool, datos)  # bool actúa como predicado
print(list(datos_limpios))  # ['valor1', 'valor2', 'valor3']
  • Validación de entradas: seleccionar solo entradas válidas
# Filtrar solo números positivos
entradas = [10, -5, 0, 15, -8, 20]
positivos = filter(lambda x: x > 0, entradas)
print(list(positivos))  # [10, 15, 20]
  • Búsqueda condicional: encontrar elementos que cumplan criterios específicos
# Encontrar archivos de Python en una lista de archivos
archivos = ["documento.txt", "script.py", "imagen.jpg", "módulo.py", "datos.csv"]
archivos_python = filter(lambda f: f.endswith('.py'), archivos)
print(list(archivos_python))  # ['script.py', 'módulo.py']

Combinando filter con otras funciones

La función filter se integra perfectamente con otras funciones de programación funcional:

# Calcular la suma de los cuadrados de los números impares
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Primero filtramos los números impares
impares = filter(lambda x: x % 2 != 0, numeros)

# Luego calculamos sus cuadrados
cuadrados_impares = map(lambda x: x**2, impares)

# Convertimos a lista y sumamos
resultado = sum(cuadrados_impares)

print(resultado)  # 165 (1 + 9 + 25 + 49 + 81)

Patrones comunes con filter

Existen varios patrones comunes al usar filter que vale la pena conocer:

Filtrado por tipo

# Filtrar solo elementos de un tipo específico
elementos = [1, "texto", 3.14, [1, 2], {"clave": "valor"}, 42, "python"]
solo_cadenas = filter(lambda x: isinstance(x, str), elementos)
print(list(solo_cadenas))  # ['texto', 'python']

Filtrado por rango

# Filtrar números dentro de un rango específico
temperaturas = [-5, 0, 10, 15, 25, 30, 35, 40]
temperatura_confortable = filter(lambda t: 18 <= t <= 25, temperaturas)
print(list(temperatura_confortable))  # [25]

Filtrado con múltiples condiciones

# Filtrar con múltiples condiciones (números pares mayores que 5)
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
resultado = filter(lambda x: x % 2 == 0 and x > 5, numeros)
print(list(resultado))  # [6, 8, 10]

Consideraciones de rendimiento

Al igual que map, la función filter es generalmente más eficiente que los bucles equivalentes para operaciones simples:

  • Está implementada en C, lo que la hace más rápida que el código Python puro
  • Utiliza evaluación perezosa, procesando elementos solo cuando se necesitan
  • Reduce la sobrecarga de las llamadas a funciones Python
# Ejemplo de filtrado de una gran lista de números
import time

# Crear una lista grande
numeros = list(range(1000000))

# Usando filter
inicio = time.time()
pares_filter = list(filter(lambda x: x % 2 == 0, numeros))
fin = time.time()
print(f"Tiempo con filter: {fin - inicio} segundos")

# Usando un bucle for
inicio = time.time()
pares_for = []
for n in numeros:
    if n % 2 == 0:
        pares_for.append(n)
fin = time.time()
print(f"Tiempo con for: {fin - inicio} segundos")

Ejemplos avanzados

Veamos algunos ejemplos más avanzados que muestran el poder de filter:

Filtrado de datos estructurados

# Filtrar registros de una base de datos simulada
registros = [
    {"id": 1, "nombre": "Ana", "activo": True, "nivel": 3},
    {"id": 2, "nombre": "Juan", "activo": False, "nivel": 2},
    {"id": 3, "nombre": "María", "activo": True, "nivel": 4},
    {"id": 4, "nombre": "Pedro", "activo": True, "nivel": 1},
    {"id": 5, "nombre": "Lucía", "activo": False, "nivel": 5}
]

# Usuarios activos con nivel >= 3
usuarios_avanzados = filter(
    lambda u: u["activo"] and u["nivel"] >= 3, 
    registros
)

print(list(usuarios_avanzados))
# [{'id': 1, 'nombre': 'Ana', 'activo': True, 'nivel': 3}, 
#  {'id': 3, 'nombre': 'María', 'activo': True, 'nivel': 4}]

Filtrado con funciones externas

def cumple_criterios(texto):
    """Verifica si un texto cumple con varios criterios"""
    # Debe tener al menos 5 caracteres
    if len(texto) < 5:
        return False
    
    # Debe contener al menos una letra mayúscula
    if not any(c.isupper() for c in texto):
        return False
    
    # Debe contener al menos un número
    if not any(c.isdigit() for c in texto):
        return False
    
    return True

# Lista de posibles contraseñas
contraseñas = [
    "abc", 
    "Password", 
    "pass123", 
    "Admin2023", 
    "secreta", 
    "P4ssw0rd"
]

# Filtrar contraseñas que cumplen los criterios
contraseñas_seguras = filter(cumple_criterios, contraseñas)
print(list(contraseñas_seguras))  # ['Admin2023', 'P4ssw0rd']

Comparativa map y filter vs comprehensions

Python ofrece múltiples enfoques para transformar y filtrar datos. Mientras que map y filter representan el paradigma de programación funcional, las comprehensions (comprensiones) son una característica distintiva de Python que proporciona una sintaxis más concisa y expresiva para realizar operaciones similares.

Equivalencias básicas

Para entender mejor las diferencias, veamos cómo se traducen las mismas operaciones entre estos enfoques:

Transformación de datos (map vs list comprehension)

# Usando map
numeros = [1, 2, 3, 4, 5]
cuadrados_map = list(map(lambda x: x**2, numeros))

# Usando list comprehension
cuadrados_comp = [x**2 for x in numeros]

print(cuadrados_map)  # [1, 4, 9, 16, 25]
print(cuadrados_comp)  # [1, 4, 9, 16, 25]

Filtrado de datos (filter vs list comprehension)

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

# Usando list comprehension
pares_comp = [x for x in numeros if x % 2 == 0]

print(pares_filter)  # [2, 4, 6, 8, 10]
print(pares_comp)    # [2, 4, 6, 8, 10]

Combinando transformación y filtrado

# Usando filter y map
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cuadrados_pares = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numeros)))

# Usando list comprehension
cuadrados_pares_comp = [x**2 for x in numeros if x % 2 == 0]

print(cuadrados_pares)      # [4, 16, 36, 64, 100]
print(cuadrados_pares_comp) # [4, 16, 36, 64, 100]

Ventajas de las comprehensions

Las comprehensions ofrecen varias ventajas sobre map y filter:

  • Legibilidad: La sintaxis de las comprehensions suele ser más intuitiva y fácil de leer, especialmente para programadores que vienen de lenguajes no funcionales.
# Comparación de legibilidad
# map y filter encadenados
resultado = list(map(lambda x: x*2, 
                    filter(lambda x: x > 5, 
                          filter(lambda x: x % 2 == 0, range(20)))))

# Equivalente con list comprehension
resultado_comp = [x*2 for x in range(20) if x % 2 == 0 if x > 5]

print(resultado)      # [12, 16, 20, 24, 28, 32, 36]
print(resultado_comp) # [12, 16, 20, 24, 28, 32, 36]
  • Expresividad: Las comprehensions permiten expresar operaciones complejas de manera más concisa y directa.

  • Versatilidad: Existen comprehensions para diferentes estructuras de datos:

# List comprehension (listas)
numeros = [1, 2, 3, 4, 5]
cuadrados = [x**2 for x in numeros]
print(cuadrados)  # [1, 4, 9, 16, 25]

# Dict comprehension (diccionarios)
cuadrados_dict = {x: x**2 for x in numeros}
print(cuadrados_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Set comprehension (conjuntos)
cuadrados_set = {x**2 for x in numeros}
print(cuadrados_set)  # {1, 4, 9, 16, 25}
  • Rendimiento: En muchos casos, las comprehensions son ligeramente más eficientes que sus equivalentes funcionales.
import timeit

# Comparación de rendimiento para una operación simple
setup = "numeros = list(range(1000))"

tiempo_map = timeit.timeit(
    "list(map(lambda x: x**2, numeros))",
    setup=setup,
    number=10000
)

tiempo_comp = timeit.timeit(
    "[x**2 for x in numeros]",
    setup=setup,
    number=10000
)

print(f"Tiempo con map: {tiempo_map:.6f} segundos")
print(f"Tiempo con comprehension: {tiempo_comp:.6f} segundos")

Ventajas de map y filter

A pesar de las ventajas de las comprehensions, map y filter tienen sus propios puntos fuertes:

  • Evaluación perezosa: Los objetos map y filter son iteradores que evalúan elementos bajo demanda, lo que puede ser más eficiente para conjuntos de datos grandes cuando no necesitas procesar todos los elementos inmediatamente.
# map es perezoso (no procesa hasta que se consume)
numeros = range(10**8)  # Rango muy grande
cuadrados = map(lambda x: x**2, numeros)

# Solo calculamos los primeros 5 elementos
for i, valor in enumerate(cuadrados):
    print(valor)
    if i >= 4:  # Después del quinto elemento
        break
# Imprime: 0, 1, 4, 9, 16
  • Compatibilidad con programación funcional: Para quienes prefieren un estilo de programación funcional más puro o vienen de otros lenguajes funcionales.

  • Flexibilidad con funciones complejas: Cuando la función a aplicar es compleja o ya está definida, map y filter pueden ser más claros.

def es_primo(n):
    """Verifica si un número es primo"""
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

# Usando filter con una función compleja
numeros = range(1, 100)
primos_filter = list(filter(es_primo, numeros))

# Equivalente con comprehension
primos_comp = [n for n in numeros if es_primo(n)]

print(primos_filter[:5])  # [2, 3, 5, 7, 11]
print(primos_comp[:5])    # [2, 3, 5, 7, 11]

Casos de uso específicos

Existen situaciones donde uno de los enfoques puede ser claramente superior:

Cuando preferir comprehensions

  • Operaciones simples donde la legibilidad es prioritaria:
# Extraer la primera letra de cada palabra
palabras = ["Python", "es", "un", "lenguaje", "poderoso"]

# Más legible con comprehension
primeras_letras = [palabra[0] for palabra in palabras]
print(primeras_letras)  # ['P', 'e', 'u', 'l', 'p']
  • Transformaciones que incluyen condiciones complejas:
# Clasificar números según múltiples condiciones
numeros = range(1, 11)
clasificados = ["par" if x % 2 == 0 else "impar" if x % 3 != 0 else "múltiplo de 3" for x in numeros]
print(clasificados)  
# ['impar', 'par', 'múltiplo de 3', 'par', 'impar', 'par', 'impar', 'par', 'múltiplo de 3', 'par']
  • Creación de estructuras de datos complejas:
# Crear una matriz (lista de listas)
matriz = [[i*j for j in range(1, 6)] for i in range(1, 6)]
for fila in matriz:
    print(fila)
# [1, 2, 3, 4, 5]
# [2, 4, 6, 8, 10]
# [3, 6, 9, 12, 15]
# [4, 8, 12, 16, 20]
# [5, 10, 15, 20, 25]

Cuando preferir map y filter

  • Cuando trabajas con funciones ya definidas que no quieres reescribir:
import math

# Lista de números
numeros = [4, 9, 16, 25, 36]

# Calcular raíz cuadrada usando la función math.sqrt
raices = list(map(math.sqrt, numeros))
print(raices)  # [2.0, 3.0, 4.0, 5.0, 6.0]
  • Cuando necesitas aplicar la misma operación a múltiples iterables:
# Sumar elementos correspondientes de tres listas
a = [1, 2, 3, 4]
b = [10, 20, 30, 40]
c = [100, 200, 300, 400]

# map puede trabajar con múltiples iterables
sumas = list(map(lambda x, y, z: x + y + z, a, b, c))
print(sumas)  # [111, 222, 333, 444]

# Esto requeriría zip con comprehension
sumas_comp = [x + y + z for x, y, z in zip(a, b, c)]
print(sumas_comp)  # [111, 222, 333, 444]
  • Cuando necesitas procesamiento perezoso para conjuntos de datos muy grandes:
# Procesamiento de un archivo grande línea por línea
def procesar_linea(linea):
    return linea.strip().upper()

# Con map (procesamiento perezoso)
with open('archivo_grande.txt', 'r') as f:
    lineas_procesadas = map(procesar_linea, f)
    # Las líneas se procesan una a una al iterar
    for i, linea in enumerate(lineas_procesadas):
        print(f"Línea {i+1}: {linea[:20]}...")  # Muestra solo los primeros 20 caracteres
        if i >= 4:  # Procesar solo 5 líneas como ejemplo
            break

Patrones idiomáticos en Python

En la comunidad Python, existen ciertas convenciones sobre cuándo usar cada enfoque:

  • Preferir comprehensions para operaciones simples y cuando la legibilidad es prioritaria.

  • Usar map y filter cuando se trabaja con funciones existentes o cuando se necesita evaluación perezosa.

  • Evitar anidar demasiadas funciones map y filter, ya que puede reducir la legibilidad.

# Evitar esto (difícil de leer)
resultado = list(map(lambda x: x**2, 
                    filter(lambda x: x % 2 == 0, 
                          map(lambda x: x + 1, range(10)))))

# Preferir esto
resultado = [x**2 for x in range(10) if (x + 1) % 2 == 0]

# O dividir en pasos si es necesario
paso1 = [x + 1 for x in range(10)]
paso2 = [x for x in paso1 if x % 2 == 0]
resultado = [x**2 for x in paso2]

Consideraciones de estilo y PEP 8

El PEP 8 (la guía de estilo oficial de Python) no establece una preferencia explícita entre comprehensions y funciones como map y filter. Sin embargo, recomienda:

  • Mantener la legibilidad como prioridad
  • Evitar líneas demasiado largas (máximo 79 caracteres)
  • Ser consistente con el estilo elegido en todo el código
# Si una comprehension es demasiado larga, divídela en múltiples líneas
resultado = [
    x**2 
    for x in range(100) 
    if x % 2 == 0 
    if x % 5 == 0
]

# O usa variables intermedias para mayor claridad
numeros = range(100)
multiplos_10 = [x for x in numeros if x % 2 == 0 and x % 5 == 0]
resultado = [x**2 for x in multiplos_10]

Resumen comparativo

Característica map/filter Comprehensions
Sintaxis Funcional Expresiva y declarativa
Legibilidad Puede ser compleja con anidamiento Generalmente más legible
Evaluación Perezosa (bajo demanda) Inmediata (genera toda la colección)
Eficiencia Buena para operaciones simples Ligeramente mejor en la mayoría de casos
Versatilidad Solo genera iteradores Puede crear listas, diccionarios y conjuntos
Múltiples iterables Soportado directamente Requiere zip o funciones adicionales
Funciones complejas Más claro con funciones predefinidas Puede volverse confuso

La elección entre map/filter y comprehensions depende del contexto específico, el estilo de programación preferido y los requisitos del proyecto. En la práctica, muchos programadores Python utilizan ambos enfoques según la situación, aprovechando las fortalezas de cada uno para escribir código más elegante y eficiente.

Aprende Python online

Otros ejercicios de programación de Python

Evalúa tus conocimientos de esta lección Funciones orden superior map y filter con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Módulo math

Python
Puzzle

Reto herencia

Python
Código

Excepciones

Python
Test

Introducción a Python

Python
Test

Reto variables

Python
Código

Funciones Python

Python
Puzzle

Reto funciones

Python
Código

Módulo datetime

Python
Test

Reto acumulación

Python
Código

Reto estructuras condicionales

Python
Código

Polimorfismo

Python
Test

Módulo os

Python
Test

Reto métodos dunder

Python
Código

Diccionarios

Python
Puzzle

Reto clases y objetos

Python
Código

Reto operadores

Python
Código

Operadores

Python
Test

Estructuras de control

Python
Puzzle

Funciones lambda

Python
Test

Reto diccionarios

Python
Código

Reto función lambda

Python
Código

Encapsulación

Python
Puzzle

Reto coleciones

Python
Proyecto

Reto funciones auxiliares

Python
Código

Crear módulos y paquetes

Python
Puzzle

Módulo datetime

Python
Puzzle

Excepciones

Python
Puzzle

Operadores

Python
Puzzle

Diccionarios

Python
Test

Reto map, filter

Python
Código

Reto tuplas

Python
Código

Proyecto gestor de tareas CRUD

Python
Proyecto

Tuplas

Python
Puzzle

Variables

Python
Puzzle

Tipos de datos

Python
Puzzle

Conjuntos

Python
Test

Reto mixins

Python
Código

Módulo csv

Python
Test

Módulo json

Python
Test

Herencia

Python
Test

Análisis de datos de ventas con Pandas

Python
Proyecto

Reto fechas y tiempo

Python
Proyecto

Reto estructuras de iteración

Python
Código

Funciones

Python
Test

Reto comprehensions

Python
Código

Variables

Python
Test

Reto serialización

Python
Proyecto

Módulo csv

Python
Puzzle

Reto polimorfismo

Python
Código

Polimorfismo

Python
Puzzle

Clases y objetos

Python
Código

Reto encapsulación

Python
Código

Estructuras de control

Python
Test

Importar módulos y paquetes

Python
Test

Módulo math

Python
Test

Funciones lambda

Python
Puzzle

Reto excepciones

Python
Código

Listas

Python
Puzzle

Reto archivos

Python
Proyecto

Encapsulación

Python
Test

Reto conjuntos

Python
Código

Clases y objetos

Python
Test

Instalación de Python y creación de proyecto

Python
Test

Reto listas

Python
Código

Tipos de datos

Python
Test

Crear módulos y paquetes

Python
Test

Tuplas

Python
Test

Herencia

Python
Puzzle

Reto acceso a sistema

Python
Proyecto

Proyecto sintaxis calculadora

Python
Proyecto

Importar módulos y paquetes

Python
Puzzle

Clases y objetos

Python
Puzzle

Módulo os

Python
Puzzle

Listas

Python
Test

Conjuntos

Python
Puzzle

Reto tipos de datos

Python
Código

Reto matemáticas

Python
Proyecto

Módulo json

Python
Puzzle

Todas las lecciones de Python

Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Python

Python

Introducción

Instalación Y Creación De Proyecto

Python

Introducción

Tema 2: Tipos De Datos, Variables Y Operadores

Python

Introducción

Instalación De Python

Python

Introducción

Tipos De Datos

Python

Sintaxis

Variables

Python

Sintaxis

Operadores

Python

Sintaxis

Estructuras De Control

Python

Sintaxis

Funciones

Python

Sintaxis

Estructuras Control Iterativo

Python

Sintaxis

Estructuras Control Condicional

Python

Sintaxis

Testing Con Pytest

Python

Sintaxis

Listas

Python

Estructuras De Datos

Tuplas

Python

Estructuras De Datos

Diccionarios

Python

Estructuras De Datos

Conjuntos

Python

Estructuras De Datos

Comprehensions

Python

Estructuras De Datos

Clases Y Objetos

Python

Programación Orientada A Objetos

Excepciones

Python

Programación Orientada A Objetos

Encapsulación

Python

Programación Orientada A Objetos

Herencia

Python

Programación Orientada A Objetos

Polimorfismo

Python

Programación Orientada A Objetos

Mixins Y Herencia Múltiple

Python

Programación Orientada A Objetos

Métodos Especiales (Dunder Methods)

Python

Programación Orientada A Objetos

Composición De Clases

Python

Programación Orientada A Objetos

Funciones Lambda

Python

Programación Funcional

Aplicación Parcial

Python

Programación Funcional

Entrada Y Salida, Manejo De Archivos

Python

Programación Funcional

Decoradores

Python

Programación Funcional

Generadores

Python

Programación Funcional

Paradigma Funcional

Python

Programación Funcional

Composición De Funciones

Python

Programación Funcional

Funciones Orden Superior Map Y Filter

Python

Programación Funcional

Funciones Auxiliares

Python

Programación Funcional

Reducción Y Acumulación

Python

Programación Funcional

Archivos Comprimidos

Python

Entrada Y Salida Io

Entrada Y Salida Avanzada

Python

Entrada Y Salida Io

Archivos Temporales

Python

Entrada Y Salida Io

Contexto With

Python

Entrada Y Salida Io

Módulo Csv

Python

Biblioteca Estándar

Módulo Json

Python

Biblioteca Estándar

Módulo Datetime

Python

Biblioteca Estándar

Módulo Math

Python

Biblioteca Estándar

Módulo Os

Python

Biblioteca Estándar

Módulo Re

Python

Biblioteca Estándar

Módulo Random

Python

Biblioteca Estándar

Módulo Time

Python

Biblioteca Estándar

Módulo Collections

Python

Biblioteca Estándar

Módulo Sys

Python

Biblioteca Estándar

Módulo Statistics

Python

Biblioteca Estándar

Módulo Pickle

Python

Biblioteca Estándar

Módulo Pathlib

Python

Biblioteca Estándar

Importar Módulos Y Paquetes

Python

Paquetes Y Módulos

Crear Módulos Y Paquetes

Python

Paquetes Y Módulos

Entornos Virtuales (Virtualenv, Venv)

Python

Entorno Y Dependencias

Gestión De Dependencias (Pip, Requirements.txt)

Python

Entorno Y Dependencias

Python-dotenv Y Variables De Entorno

Python

Entorno Y Dependencias

Acceso A Datos Con Mysql, Pymongo Y Pandas

Python

Acceso A Bases De Datos

Acceso A Mongodb Con Pymongo

Python

Acceso A Bases De Datos

Acceso A Mysql Con Mysql Connector

Python

Acceso A Bases De Datos

Novedades Python 3.13

Python

Características Modernas

Operador Walrus

Python

Características Modernas

Pattern Matching

Python

Características Modernas

Instalación Beautiful Soup

Python

Web Scraping

Sintaxis General De Beautiful Soup

Python

Web Scraping

Tipos De Selectores

Python

Web Scraping

Web Scraping De Html

Python

Web Scraping

Web Scraping Para Ciencia De Datos

Python

Web Scraping

Autenticación Y Acceso A Recursos Protegidos

Python

Web Scraping

Combinación De Selenium Con Beautiful Soup

Python

Web Scraping

Accede GRATIS a Python y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender el funcionamiento y sintaxis de la función map para transformar elementos de iterables.
  • Aprender a usar filter para seleccionar elementos que cumplen una condición.
  • Conocer las características de evaluación perezosa y objetos iterables que devuelven map y filter.
  • Aplicar map y filter en casos prácticos y combinarlos con otras funciones funcionales.
  • Comparar map y filter con las comprehensions de Python, entendiendo ventajas y casos de uso de cada enfoque.