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ícateMap
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 aFalse
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
yfilter
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
yfilter
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
yfilter
cuando se trabaja con funciones existentes o cuando se necesita evaluación perezosa.Evitar anidar demasiadas funciones
map
yfilter
, 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.
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
Reto herencia
Excepciones
Introducción a Python
Reto variables
Funciones Python
Reto funciones
Módulo datetime
Reto acumulación
Reto estructuras condicionales
Polimorfismo
Módulo os
Reto métodos dunder
Diccionarios
Reto clases y objetos
Reto operadores
Operadores
Estructuras de control
Funciones lambda
Reto diccionarios
Reto función lambda
Encapsulación
Reto coleciones
Reto funciones auxiliares
Crear módulos y paquetes
Módulo datetime
Excepciones
Operadores
Diccionarios
Reto map, filter
Reto tuplas
Proyecto gestor de tareas CRUD
Tuplas
Variables
Tipos de datos
Conjuntos
Reto mixins
Módulo csv
Módulo json
Herencia
Análisis de datos de ventas con Pandas
Reto fechas y tiempo
Reto estructuras de iteración
Funciones
Reto comprehensions
Variables
Reto serialización
Módulo csv
Reto polimorfismo
Polimorfismo
Clases y objetos
Reto encapsulación
Estructuras de control
Importar módulos y paquetes
Módulo math
Funciones lambda
Reto excepciones
Listas
Reto archivos
Encapsulación
Reto conjuntos
Clases y objetos
Instalación de Python y creación de proyecto
Reto listas
Tipos de datos
Crear módulos y paquetes
Tuplas
Herencia
Reto acceso a sistema
Proyecto sintaxis calculadora
Importar módulos y paquetes
Clases y objetos
Módulo os
Listas
Conjuntos
Reto tipos de datos
Reto matemáticas
Módulo json
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
Introducción
Instalación Y Creación De Proyecto
Introducción
Tema 2: Tipos De Datos, Variables Y Operadores
Introducción
Instalación De Python
Introducción
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Estructuras Control Iterativo
Sintaxis
Estructuras Control Condicional
Sintaxis
Testing Con Pytest
Sintaxis
Listas
Estructuras De Datos
Tuplas
Estructuras De Datos
Diccionarios
Estructuras De Datos
Conjuntos
Estructuras De Datos
Comprehensions
Estructuras De Datos
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Mixins Y Herencia Múltiple
Programación Orientada A Objetos
Métodos Especiales (Dunder Methods)
Programación Orientada A Objetos
Composición De Clases
Programación Orientada A Objetos
Funciones Lambda
Programación Funcional
Aplicación Parcial
Programación Funcional
Entrada Y Salida, Manejo De Archivos
Programación Funcional
Decoradores
Programación Funcional
Generadores
Programación Funcional
Paradigma Funcional
Programación Funcional
Composición De Funciones
Programación Funcional
Funciones Orden Superior Map Y Filter
Programación Funcional
Funciones Auxiliares
Programación Funcional
Reducción Y Acumulación
Programación Funcional
Archivos Comprimidos
Entrada Y Salida Io
Entrada Y Salida Avanzada
Entrada Y Salida Io
Archivos Temporales
Entrada Y Salida Io
Contexto With
Entrada Y Salida Io
Módulo Csv
Biblioteca Estándar
Módulo Json
Biblioteca Estándar
Módulo Datetime
Biblioteca Estándar
Módulo Math
Biblioteca Estándar
Módulo Os
Biblioteca Estándar
Módulo Re
Biblioteca Estándar
Módulo Random
Biblioteca Estándar
Módulo Time
Biblioteca Estándar
Módulo Collections
Biblioteca Estándar
Módulo Sys
Biblioteca Estándar
Módulo Statistics
Biblioteca Estándar
Módulo Pickle
Biblioteca Estándar
Módulo Pathlib
Biblioteca Estándar
Importar Módulos Y Paquetes
Paquetes Y Módulos
Crear Módulos Y Paquetes
Paquetes Y Módulos
Entornos Virtuales (Virtualenv, Venv)
Entorno Y Dependencias
Gestión De Dependencias (Pip, Requirements.txt)
Entorno Y Dependencias
Python-dotenv Y Variables De Entorno
Entorno Y Dependencias
Acceso A Datos Con Mysql, Pymongo Y Pandas
Acceso A Bases De Datos
Acceso A Mongodb Con Pymongo
Acceso A Bases De Datos
Acceso A Mysql Con Mysql Connector
Acceso A Bases De Datos
Novedades Python 3.13
Características Modernas
Operador Walrus
Características Modernas
Pattern Matching
Características Modernas
Instalación Beautiful Soup
Web Scraping
Sintaxis General De Beautiful Soup
Web Scraping
Tipos De Selectores
Web Scraping
Web Scraping De Html
Web Scraping
Web Scraping Para Ciencia De Datos
Web Scraping
Autenticación Y Acceso A Recursos Protegidos
Web Scraping
Combinación De Selenium Con Beautiful Soup
Web Scraping
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.