Una list comprehension es una forma compacta de crear listas en Python combinando un bucle y, opcionalmente, un filtro en una sola línea. El resultado es código más legible y, en muchos casos, más rápido que el equivalente con for y append().
Sintaxis básica
La forma más simple transforma cada elemento de un iterable:
# Forma larga
cuadrados = []
for x in range(10):
cuadrados.append(x ** 2)
# List comprehension equivalente
cuadrados = [x ** 2 for x in range(10)]
print(cuadrados) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Añadir una condición para filtrar
La cláusula if al final filtra los elementos antes de aplicar la expresión:
# Solo los pares pares = [x for x in range(20) if x % 2 == 0] print(pares) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # Filtrar y transformar a la vez palabras = ["hola", "", "mundo", "", "python"] no_vacias = [p.upper() for p in palabras if p] print(no_vacias) # ['HOLA', 'MUNDO', 'PYTHON']
Comprehensions anidadas
Puedes anidar bucles para trabajar con matrices o combinaciones. El orden de los for en la comprehension es el mismo que en los bucles anidados:
# Aplanar una matriz 3x3
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
plana = [num for fila in matriz for num in fila]
print(plana) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Tabla de multiplicar 3x3
tabla = [(i, j, i*j) for i in range(1, 4) for j in range(1, 4)]
for fila in tabla:
print(f"{fila[0]} x {fila[1]} = {fila[2]}")
Dict y set comprehensions
La misma sintaxis funciona para diccionarios (con {clave: valor ...}) y conjuntos (con {expresión ...}):
# Dict comprehension: invertir un diccionario
original = {"a": 1, "b": 2, "c": 3}
invertido = {v: k for k, v in original.items()}
print(invertido) # {1: 'a', 2: 'b', 3: 'c'}
# Dict comprehension con filtro
precios = {"manzana": 1.2, "pera": 0.8, "uva": 2.5, "kiwi": 1.9}
caros = {nombre: precio for nombre, precio in precios.items() if precio > 1.5}
print(caros) # {'uva': 2.5, 'kiwi': 1.9}
# Set comprehension: caracteres únicos
texto = "programacion python"
letras = {c for c in texto if c != " "}
print(letras) # conjunto de letras sin orden garantizado
Cuándo usarlas y cuándo no
Las list comprehensions son ideales cuando la lógica es simple y cabe en una línea legible. Cuando la transformación requiere varias líneas, un bucle for tradicional es más claro:
# BIEN: lógica simple, una línea clara
activos = [u for u in usuarios if u.activo]
# MAL: demasiado complejo para una comprehension
# resultado = [procesar(x) if condicion_compleja(x) else alternativa(x)
# for x in datos if filtro_uno(x) and filtro_dos(x)]
# MEJOR: bucle for normal con comentarios
resultado = []
for x in datos:
if filtro_uno(x) and filtro_dos(x):
if condicion_compleja(x):
resultado.append(procesar(x))
else:
resultado.append(alternativa(x))
Si la comprehension no cabe en 80 caracteres sin retorcerla, escríbela como un bucle for. La legibilidad siempre gana.
