Una línea, una idea
Ya has escrito el patrón varias veces: empieza con una lista vacía, itera sobre algo, quizá filtra y haz append al resultado.
Una list comprehension dice lo mismo en una línea:
Léela de izquierda a derecha: "una nueva lista que consiste en n * 2, por cada n en numbers". La estructura es [expresión for elemento in iterable].
No es un truco específico de Python — se llama comprehension porque estás describiendo lo que va en la nueva lista, de forma declarativa, en vez de escribir la mecánica de cómo construirla.
Añadir un filtro
Pon una cláusula if después de la parte del bucle para filtrar:
Lee la segunda como: "n * n por cada n en numbers, pero solo si n es impar".
El bucle equivalente:
Ambos están bien. La comprehension es más corta y, una vez que has leído unas pocas, realmente más fácil de escanear porque la intención está ahí mismo en una línea.
Map y filter combinados
Puedes leer valores a través de una función y filtrar al mismo tiempo:
Por cada palabra con más de 3 letras, incluye su versión en mayúsculas.
Bucles anidados en una comprehension
Dos for producen un par estilo producto cartesiano:
El orden es el mismo que si hubieses anidado los bucles: el primer for es el externo, el segundo el interno. Se lee de izquierda a derecha como el bucle indentado equivalente.
Dos niveles es aproximadamente el límite antes de que un bucle normal se lea mejor. Si llegas a tres, vuelve a los bucles.
Dict y set comprehensions
Misma idea, llaves distintas:
Las set comprehensions parecen idénticas a las dict comprehensions a primera vista — la diferencia es key: value vs una sola expresión. Llaves más : = dict; llaves sin : = set.
Expresiones generadoras
Una casi-gemela de la list comprehension, pero con paréntesis en vez de corchetes — y crucialmente, no construye una lista:
Fíjate en que pasamos el generador directamente a sum() y any() — sin paréntesis extra. Las expresiones generadoras son la herramienta correcta cuando quien llama solo necesita iterar una vez. Son más amables con la memoria que una lista completa para colecciones grandes.
Cuándo usar un bucle normal en su lugar
Las comprehensions son seductoras. Técnicamente puedes meter mucho en una. No deberías.
Recurre a un bucle normal cuando:
- La transformación tiene más de un paso. Si necesitas variables intermedias, escríbelo.
- Hay manejo de errores o ramificación complejos.
- Cualquiera que lea la línea tiene que pausar más de una vez para entenderla.
La regla que aplico: si puedo leer la comprehension de un tirón y entender lo que hace, se queda. Si tropiezo, la reescribo como bucle.
Algunas comprehensions parecen astutas pero duelen:
Mismo resultado. La versión en bucle son cinco líneas en vez de una, pero "más largo" no es lo mismo que "peor".
Algunos patrones que reutilizarás
Esos cinco patrones cubren una cantidad sorprendente de trabajo diario con datos.
Siguiente
Ya has visto los principales tipos de colección y la comprehension que los une. Siguiente capítulo: funciones — empaquetar comportamiento en unidades con nombre y reusables.
Preguntas frecuentes
¿Qué es una list comprehension en Python?
Una sintaxis compacta para construir una nueva lista desde un iterable existente. [x * 2 for x in numbers] crea una nueva lista con cada número duplicado. También puedes filtrar: [x for x in numbers if x > 0].
¿Cuándo no debería usar una list comprehension?
Cuando dañe la legibilidad. Si la expresión de dentro es compleja o está profundamente anidada, un bucle for normal con nombres de variable apropiados es más claro. Las comprehensions son para transformaciones simples — mapeo y filtrado. Cualquier cosa más compleja va mejor en un bucle completo.
¿Cuál es la diferencia entre una list comprehension y una expresión generadora?
Una list comprehension construye la lista entera en memoria. Una expresión generadora (misma sintaxis pero con paréntesis) produce un elemento cada vez. Usa un generador cuando alimentes los resultados a algo que itera una sola vez — como sum(...) — así no materializas una lista que vas a tirar inmediatamente.