Una comprensión construye una colección nueva en una sola línea, aplicando una transformación y —si quieres— un filtro. Es Python idiomático: lo que en otros lenguajes son 4 líneas de bucle, aquí es 1.
De bucle a comprensión
Este bucle clásico:
cuadrados = []
for x in range(1, 6):
cuadrados.append(x ** 2)
print(cuadrados) # [1, 4, 9, 16, 25]
Se convierte en:
cuadrados = [x ** 2 for x in range(1, 6)]
print(cuadrados) # [1, 4, 9, 16, 25]
Lee la línea así: "la expresión x ** 2, para cada x en el rango".
La anatomía
[expresion for elemento in coleccion if condicion]
Las tres partes:
expresion— qué poner en la lista nueva (puede transformar el elemento)for elemento in coleccion— de dónde salen los datosif condicion(opcional) — filtro: solo pasan los que la cumplen
Con filtro
numeros = [1, 2, 3, 4, 5, 6, 7, 8]
pares = [n for n in numeros if n % 2 == 0]
print(pares) # [2, 4, 6, 8]
grandes = [n for n in numeros if n > 4]
print(grandes) # [5, 6, 7, 8]
Transformar y filtrar a la vez
palabras = ["hola", "adios", "si", "no", "python"]
mayusculas_largas = [p.upper() for p in palabras if len(p) > 3]
print(mayusculas_largas) # ['HOLA', 'ADIOS', 'PYTHON']
Comprehensions de diccionarios y sets
Cambia los corchetes y defines el tipo:
nombres = ["ana", "luis", "maria"]
# dict comprehension: clave: valor
longitudes = {n: len(n) for n in nombres}
print(longitudes) # {'ana': 3, 'luis': 4, 'maria': 5}
# set comprehension: con llaves
iniciales = {n[0] for n in nombres}
print(iniciales) # {'a', 'l', 'm'}
La trampa del anidamiento
Las comprensiones anidadas existen, pero legibilidad < 2 niveles:
matriz = [[1, 2], [3, 4], [5, 6]]
# aplanar: ok, legible
plana = [num for fila in matriz for num in fila]
print(plana) # [1, 2, 3, 4, 5, 6]
Cuando la comprensión no cabe en una línea o necesitas pensarla dos veces, usa un bucle normal. El Zen de Python: legible counts.
¿Cuándo NO usarlas?
# MAL: efectos secundarios dentro de una comprensión
[print(x) for x in range(3)] # funciona, pero es abuso
# BIEN: para efectos secundarios, bucle normal
for x in range(3):
print(x)
Las comprensiones existen para construir colecciones, no para ejecutar acciones.
Resumen
[expresion for x in coleccion if condicion]— transformar, recorrer, filtrar{k: v for ...}diccionarios;{x for ...}sets- Si deja de ser legible, vuelve al bucle
for - Úsalas para construir datos, no para efectos secundarios