Las list comprehensions son una de las características más reconocibles de Python. Permiten crear una lista nueva a partir de un iterable, aplicando una transformación y, de forma opcional, un filtro. Bien utilizadas eliminan código repetitivo; mal utilizadas concentran demasiada lógica en una sola línea.
En esta guía aprenderás list comprehensions en Python desde la sintaxis básica hasta condiciones, bucles anidados, diccionarios, sets, expresiones generadoras y decisiones de estilo. Conviene conocer primero los bucles for en Python y las listas en Python.
Patrón básico
La forma general es [expresion for elemento in iterable].
numeros = [1, 2, 3, 4, 5]
cuadrados = [numero ** 2 for numero in numeros]
print(cuadrados)El bucle equivalente es más largo, pero realiza los mismos pasos.
cuadrados = []
for numero in numeros:
cuadrados.append(numero ** 2)Transformar strings
nombres = [" ada ", "GRACE", " guido"]
limpios = [nombre.strip().title() for nombre in nombres]
print(limpios)La expresión puede llamar métodos y funciones. Mantén una única transformación fácil de comprender. Para operaciones complejas, utiliza una función con nombre; la guía de funciones en Python explica cómo organizarlas.
Filtrar con if
Coloca un if después del bucle para incluir solamente los elementos que cumplen la condición.
numeros = range(1, 21)
cuadrados_pares = [
numero ** 2
for numero in numeros
if numero % 2 == 0
]
print(cuadrados_pares)Condición if/else dentro de la expresión
Un if/else antes del for transforma todos los elementos en lugar de filtrarlos.
puntuaciones = [95, 72, 88, 61]
etiquetas = [
"aprobado" if nota >= 70 else "suspenso"
for nota in puntuaciones
]Compara ambos patrones:
[x for x in valores if condicion]elimina elementos.[a if condicion else b for x in valores]conserva todos y elige un resultado.
Extraer la lógica compleja
def normalizar_correo(valor):
correo = valor.strip().lower()
if "@" not in correo:
raise ValueError(f"Correo inválido: {valor!r}")
return correo
entradas = [" [email protected] ", "[email protected]"]
correos = [normalizar_correo(valor) for valor in entradas]La validación permanece en una función que puede probarse de forma independiente.
Bucles anidados
Una comprensión puede contener varios for. El orden coincide con los bucles anidados normales.
pares = [
(letra, numero)
for letra in ["A", "B"]
for numero in [1, 2, 3]
]
print(pares)Uno o dos niveles breves pueden ser legibles. Una comprensión profundamente anidada debería convertirse en bucles o funciones.
Aplanar una lista de listas
matriz = [
[1, 2, 3],
[4, 5, 6],
]
plana = [valor for fila in matriz for valor in fila]
print(plana)Crear una matriz correctamente
filas = 3
columnas = 4
matriz = [
[0 for _ in range(columnas)]
for _ in range(filas)
]Cada comprensión interna crea una lista distinta. Evita [[0] * columnas] * filas, porque repetiría referencias a la misma lista interna.
Dictionary comprehensions
palabras = ["python", "api", "database"]
longitudes = {
palabra: len(palabra)
for palabra in palabras
}
print(longitudes)Para trabajar con claves y valores, consulta la guía de diccionarios en Python.
Set comprehensions
palabras = ["python", "programa", "api", "python"]
iniciales = {palabra[0].upper() for palabra in palabras}
print(iniciales)Los sets eliminan duplicados. La guía de sets en Python explica unión, intersección y diferencia.
Comprensión frente a map()
valores = ["1", "2", "3"]
con_comprension = [int(valor) for valor in valores]
con_map = list(map(int, valores))Una comprensión suele ser clara cuando la transformación es una expresión breve. map() puede resultar elegante cuando ya existe una función con nombre.
Lista frente a generador
Los corchetes crean todos los valores inmediatamente. Los paréntesis crean una expresión generadora que produce valores bajo demanda.
lista = [numero ** 2 for numero in range(1000)]
generador = (numero ** 2 for numero in range(1000))
print(type(lista).__name__)
print(type(generador).__name__)Utiliza una lista cuando necesites índices, longitud o varias iteraciones. Utiliza un generador cuando los valores se consuman una vez y el volumen pueda ser grande.
Evitar efectos secundarios
Una comprensión debería crear una colección. No la utilices solamente para imprimir, modificar variables globales o escribir archivos.
nombres = ["Maya", "Noah", "Liam"]
for nombre in nombres:
print(nombre)Ejemplo práctico de limpieza
registros = [
{"nombre": " Ada ", "activo": True, "nota": "91"},
{"nombre": "Grace", "activo": False, "nota": "88"},
{"nombre": " Guido ", "activo": True, "nota": "95"},
]
usuarios_activos = [
{
"nombre": registro["nombre"].strip(),
"nota": int(registro["nota"]),
}
for registro in registros
if registro["activo"]
]La comprensión es adecuada porque la transformación y el filtro siguen siendo breves. Si pueden faltar claves o aparecer números inválidos, un bucle con manejo de errores es más claro.
Errores frecuentes
- Escribir una comprensión demasiado larga.
- Confundir el
ifde filtro con elif/elsede transformación. - Usarla únicamente para efectos secundarios.
- Crear una lista enorme cuando un generador sería suficiente.
- Añadir demasiados bucles y condiciones.
- Creer que modifica la lista de origen.
Conclusión
Las list comprehensions en Python son ideales para una transformación clara con un filtro opcional sencillo. Extrae la lógica compleja a funciones, cambia a bucles normales cuando necesites acciones o informes de errores y utiliza generadores cuando materializar todos los resultados desperdicie memoria.
Documentación oficial
La guía oficial de Python explica las comprensiones de listas, mientras que PEP 202 documenta el diseño que introdujo esta sintaxis en el lenguaje.






