Comprensión de listas

# ─────────────────────────────────────────────
# COMPRENSIÓN DE LISTAS (List Comprehensions)
# ─────────────────────────────────────────────
# Es una forma compacta de crear una lista nueva a partir de otra.
# Sintaxis básica:
#
#   nueva_lista = [expresion for elemento in iterable]
#
# Equivale exactamente a:
#
#   nueva_lista = []
#   for elemento in iterable:
#       nueva_lista.append(expresion)


# ─────────────────────────────────────────────
# TRANSFORMACIÓN: aplicar una operación a cada elemento
# ─────────────────────────────────────────────

lista = [1, 2, 3, 4, 5, 6]

# Por cada número de la lista, guardamos ese número multiplicado por 2
dobles = [numero * 2 for numero in lista]
print(dobles)   # → [2, 4, 6, 8, 10, 12]

# 💡 EQUIVALENTE con for tradicional (hace exactamente lo mismo):
dobles = []
for numero in lista:
    dobles.append(numero * 2)


# ─────────────────────────────────────────────
# TRANSFORMAR CADENAS
# ─────────────────────────────────────────────

alumnos = ["ana", "jUAN", "pep", "IU", "Eva"]

# .title() pone en mayúscula la primera letra de cada palabra y el resto en minúscula
alumnos_bien = [alumno.title() for alumno in alumnos]
print(alumnos_bien)   # → ['Ana', 'Juan', 'Pep', 'Iu', 'Eva']

# 💡 ALTERNATIVAS a .title() para normalizar texto:
# "jUAN".upper()      → "JUAN"     todo mayúsculas
# "jUAN".lower()      → "juan"     todo minúsculas
# "jUAN".capitalize() → "Juan"     solo la primera letra en mayúscula
# "jUAN".title()      → "Juan"     mayúscula al inicio de cada palabra

# [0:2] → slice con los dos primeros caracteres de cada nombre
alumnos_comienzos = [alumno[0:2] for alumno in alumnos]
print(alumnos_comienzos)   # → ['an', 'jU', 'pe', 'IU', 'Ev']


# ─────────────────────────────────────────────
# USAR EL ELEMENTO COMO CANTIDAD
# ─────────────────────────────────────────────

lista = [2, 4, 5, 3]

# El número indica cuántas veces repetimos el carácter "*"
# "*" * 3  →  "***"
asteriscos = ["*" * n for n in lista]
print(asteriscos)   # → ['**', '****', '*****', '***']

# 💡 ALTERNATIVA: usar otro carácter o construir una barra de progreso
barras = ["█" * n for n in lista]
print(barras)   # → ['██', '████', '█████', '███']


# ─────────────────────────────────────────────
# COMBINAR SLICE Y COMPRENSIÓN
# ─────────────────────────────────────────────

letras = "abcdefghijklmnopqrstuvwxyz"

# Para cada n de la lista, tomamos los primeros n caracteres del abecedario
# letras[0:2] → "ab" | letras[0:4] → "abcd" | letras[0:5] → "abcde"
comienzos = [letras[0:n] for n in lista]
print(comienzos)   # → ['ab', 'abcd', 'abcde', 'abc']


# ─────────────────────────────────────────────
# COPIA DE UNA LISTA
# ─────────────────────────────────────────────

# Si la expresión es simplemente el propio elemento, obtenemos una copia
lista_igual = [n for n in lista]
print(lista_igual)   # → [2, 4, 5, 3]

# 💡 ALTERNATIVA más directa para copiar una lista:
# lista_igual = lista.copy()
# lista_igual = lista[:]


# ─────────────────────────────────────────────
# FILTRADO: añadir una condición con 'if'
# ─────────────────────────────────────────────
# Sintaxis con filtro:
#
#   nueva_lista = [expresion for elemento in iterable if condicion]
#
# Solo se incluyen los elementos que cumplen la condición.

palabras = ["patata", "bustrofedónico", "alubia",
            "otorrinolaringólogo", "mesa", "supercalifragilísticoespialidoso"]

# Solo incluimos la palabra si su longitud (len) es mayor de 10
palabras_largas = [palabra for palabra in palabras if len(palabra) > 10]
print(palabras_largas)   # → ['bustrofedónico', 'otorrinolaringólogo', 'supercalifragilísticoespialidoso']

# 💡 ALTERNATIVAS de filtrado:
palabras_cortas  = [p for p in palabras if len(p) <= 5]     # longitud ≤ 5
con_a            = [p for p in palabras if p.startswith('a')] # que empiecen por 'a'
con_vocal_final  = [p for p in palabras if p[-1] in 'aeiou'] # acaban en vocal


# ─────────────────────────────────────────────
# COMBINAR FILTRADO Y TRANSFORMACIÓN
# ─────────────────────────────────────────────
# La expresión y la condición pueden ser distintas:
# · la condición decide SI se incluye el elemento
# · la expresión decide QUÉ se guarda de ese elemento

# Objetivo: de una lista de nombres, quedarse solo con los de
# longitud PAR e invertirlos.
# ["Pep","Iu","Eva","Juan"] → longitud par: "Iu"(2), "Juan"(4) → invertidos: ["uI","nauJ"]

lista = ["Pep", "Iu", "Eva", "Juan"]

# Paso a paso:
#   1. if len(i) % 2 == 0 → filtra: solo "Iu" y "Juan" tienen longitud par
#   2. i[::-1]            → transforma: invierte cada cadena seleccionada
par_invertidas = [i[::-1] for i in lista if len(i) % 2 == 0]
print(par_invertidas)   # → ['uI', 'nauJ']

# 💡 EQUIVALENTE con for tradicional, más explicado:
par_invertidas = []
for i in lista:
    if len(i) % 2 == 0:       # condición: longitud par
        par_invertidas.append(i[::-1])   # transformación: invertir

# 💡 ALTERNATIVA: guardar también el original para comparar
pares_con_original = [(i, i[::-1]) for i in lista if len(i) % 2 == 0]
print(pares_con_original)   # → [('Iu', 'uI'), ('Juan', 'nauJ')]

Anatomía de una comprensión de lista

resultado = [ expresión   for elemento in iterable   if condición ]
               │                │             │            │
               │                │             │            └── (opcional) filtro:
               │                │             │                solo los que cumplan esto
               │                │             └─────────────── de dónde vienen los datos
               │                └───────────────────────────── nombre temporal
               └────────────────────────────────────────────── qué guardamos

Comparativa: for tradicional vs comprensión

Con for tradicional Con comprensión
resultado = [] + for + append() Todo en una línea
Más fácil de leer al principio Más compacto y expresivo
Fácil de depurar paso a paso Ideal cuando la lógica es simple
Mejor si hay lógica compleja Evitar si hay más de una condición

Los tres sabores de la comprensión

# 1. Solo transformación
[expresion for x in lista]

# 2. Solo filtrado
[x for x in lista if condicion]

# 3. Transformación + filtrado
[expresion for x in lista if condicion]

💡 Regla de oro: si el for + if cabe en una línea corta y se lee de forma natural, usa comprensión. Si necesitas anidar dos for, añadir varios if o la lógica es compleja, el for tradicional será más claro y fácil de mantener.

Publicado por

Juan Pablo Fuentes

Formador de programación y bases de datos