Comprensiones
Construye listas, dicts y sets de forma concisa con la sintaxis de comprensión.
- Escribir comprensiones de lista con filtrado y condiciones
- Crear comprensiones de dict y de set
- Usar comprensiones anidadas para estructuras 2D
- Saber cuándo usar una comprensión frente a un bucle normal
La notación de construcción de conjuntos, hecha código
Las matemáticas tienen una forma compacta de describir una colección construida desde otra: el constructor de conjuntos. La comprensión es esa notación, tecleada directamente:
Lee “el conjunto de , para cada en esta fuente”, y el Python es la misma frase invertida en código:
# Bucle normal
squares = []
for x in range(6):
squares.append(x ** 2)
# Comprensión
squares = [x ** 2 for x in range(6)]
# [0, 1, 4, 9, 16, 25]El bucle deletrea tres movimientos, empezar vacío, añadir, repetir; la comprensión enuncia toda la colección en una línea que refleja la anatomía del constructor: la expresión al frente, la variable recorrida detrás.
Filtrar con condiciones
La notación de construcción también lleva pruebas de pertenencia. se vuelve un if final:
evens = [x for x in range(10) if x % 2 == 0]
# [0, 2, 4, 6, 8]
long_words = [w.upper() for w in ["hi", "hello", "hey"] if len(w) > 2]
# ['HELLO', 'HEY']Un if al final es un filtro: solo los elementos que lo superan llegan a la expresión. El elemento viaja expresión → filtro → lista, en el orden en que la frase se lee.
If/else como expresión
El if...else que ya conoces es una expresión, produce un valor. Pegar uno antes del for lo planta en la línea de construcción, eligiendo por elemento en lugar de filtrar por elemento:
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
# ['even', 'odd', 'even', 'odd', 'even']Las dos posiciones son una bifurcación con trabajos distintos: después del for, la cláusula vota sobre los elementos; antes del for, los etiqueta. Uno descarta, el otro transforma.
Comprensiones de dict
La misma forma construye mapeos, la expresión a la izquierda de los dos puntos se vuelve la clave, y la de la derecha el valor:
squares_dict = {x: x**2 for x in range(6)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Invierte un dict
original = {"a": 1, "b": 2}
inverted = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b'}La inversión es el clásico elegante: recorre items() e intercambia qué mitad de cada par pasa a ser la clave.
Comprensiones de set
Las llaves con una comprensión producen un set, unicidad aplicada automáticamente:
lengths = {len(word) for word in ["hello", "hi", "hey"]}
# {2, 3, 5} (longitudes únicas)Tres longitudes colapsan a un conjunto de valores, dejando caer el duplicado como un set debe.
Comprensiones anidadas: la aplanadora
Una matriz es una lista de filas, y aplanarla son dos bucles en una expresión, lee las cláusulas for de izquierda a derecha, la exterior primero:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]Cada for desenvuelve un nivel: row recorre la lista exterior, num recorre cada fila, y el orden de la colección sigue a los bucles exactamente.
Un ejemplo resuelto: tres líneas desde el constructor de conjuntos
Los tres movimientos de la lección, construir, filtrar, etiquetar, una línea cada uno:
squares = [x ** 2 for x in range(2, 9)]
# [4, 9, 16, 25, 36, 49, 64]
numbers = [x for x in range(1, 11) if x % 3 == 0]
# [3, 6, 9]
labels = ["even" if x % 2 == 0 else "odd" for x in numbers]
# ['odd', 'even', 'odd']El primero es , tipeado a secas; el segundo filtra los divisores de ; el tercero etiqueta a cada sobreviviente. Lo que el constructor de conjuntos dice de un aliento, la comprensión lo deletrea en una línea.
Cuándo NO usar comprensiones
- Cuando la lógica se anuda, un bucle
fornormal se gana su legibilidad. - Cuando el cuerpo necesita
try/except, las comprensiones no tienen sitio para él. - Cuando importan los efectos secundarios, imprimir o escribir archivos deben ser sentencias deliberadas, no expresiones silenciosas.
- Poner
ifantes delforetiqueta en vez de filtrar.[x if x % 2 == 0 else 'odd' for x in ...]conserva todo elemento, apenas renombrado; solo unifdespués delfordescarta. Mal ubicado, los rechazados se quedan callados.
🧩 Desafíos
🧩 Desafío, piensa primero, luego revela
Aplana [[1, 2], [3, 4], [5, 6]] hasta [1, 2, 3, 4, 5, 6] con una comprensión.
💡 Respuesta: [num for row in matrix for num in row], el for exterior abre cada fila, el interior la extiende.
🧩 Desafío, piensa primero, luego revela
Mapea palabras a sus longitudes con una comprensión de dict: ["hi", "hello", "hey"] → {"hi": 2, "hello": 5, "hey": 3}.
💡 Respuesta: {w: len(w) for w in words}, la palabra es la clave y su longitud el valor, un par por entrada.
🤔 Preguntas socráticas
- ¿Por qué va
if...elseantes delforen una comprensión mientras que elifde filtro va detrás? - ¿Dónde cruza una comprensión la línea hacia una lectura más dura que un bucle? ¿Dónde la trazas?
- ¿Puede aparecer
awaitdentro de una comprensión, y qué sintaxis hace posible toda una versión asíncrona?
✅ Comprobación rápida
1. ¿Qué produce [x * 2 for x in range(4) if x > 1]?
2. ¿Cuál es la comprensión de dict correcta?