Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Proyecto II: El Analizador de Texto

El proyecto integrador construyó un almacén de productos. Este miniproyecto es más corto y ataca otra habilidad: procesar texto. Vas a leer un archivo y averiguar qué palabras aparecen más veces. Es la base de cosas tan reales como un buscador o un detector de spam.

A diferencia de los ejercicios, aquí sí te muestro la solución paso a paso. Pero inténtalo primero: el plano completo está en estas cuatro piezas.

El Reto

Dado un archivo de texto, el programa debe:

  1. Leer todo su contenido.
  2. Contar cuántas veces aparece cada palabra (sin distinguir mayúsculas).
  3. Mostrar las 5 palabras más frecuentes.

Pieza 1: Conseguir el texto

Para no depender de tener un archivo a mano, lo creamos en el momento. En un caso real, este texto vendría de Path("documento.txt").read_text().

texto = """
el almacén guarda cajas el almacén ordena cajas
el gerente cuenta cajas y el gerente revisa cajas
"""

Pieza 2: Partir en palabras y normalizar

.lower() iguala mayúsculas y minúsculas; .split() sin argumentos parte por cualquier espacio o salto de línea y descarta los vacíos.

palabras = texto.lower().split()

Pieza 3: Contar con un diccionario

El patrón acumulador, pero sobre un diccionario: la clave es la palabra, el valor es cuántas veces apareció. .get(palabra, 0) devuelve el conteo actual (o 0 la primera vez), le sumamos uno y lo guardamos.

conteo: dict[str, int] = {}
for palabra in palabras:
    conteo[palabra] = conteo.get(palabra, 0) + 1

Aquí se ve por qué .get() con valor por defecto es tan útil: sin él, la primera vez que ves una palabra obtienes un KeyError.

Pieza 4: Ordenar y mostrar el top 5

El sorted() que conociste en el Capítulo 5 ordena las parejas por su conteo, de mayor a menor. Las piezas nuevas son dos: key, que le dice por qué campo ordenar (el valor, no la clave), y esa criatura llamada lambda. El orden “de mayor a menor” lo pone reverse=True; sin él, sorted() ordena de menor a mayor.

ranking = sorted(conteo.items(), key=lambda par: par[1], reverse=True)

print("Top 5 palabras:")
for palabra, veces in ranking[:5]:
    print(f"{veces:>3}  {palabra}")

Nota: así se lee una lambda. Es una función sin nombre, escrita en una línea. lambda par: par[1] equivale exactamente a esto:

def obtener_conteo(par):
    return par[1]

Es decir: “recibe par y devuelve par[1]”. sorted la llama con cada pareja ("cajas", 4) para saber por cuál número ordenar. Podrías escribir la versión con def y pasarle key=obtener_conteo: resultado idéntico. La lambda solo se ahorra el nombre cuando la función es tan pequeña que no lo merece. Si te estorba, usa def; nadie te va a multar.

ranking[:5] es el rebanado que ya conoces: solo las cinco primeras. Y {veces:>3} alinea los números a la derecha en tres espacios, para que la lista quede en columna.

El Archivo Completo

def contar_palabras(texto: str) -> dict[str, int]:
    """Cuenta cuántas veces aparece cada palabra, sin distinguir mayúsculas."""
    conteo: dict[str, int] = {}
    for palabra in texto.lower().split():
        conteo[palabra] = conteo.get(palabra, 0) + 1
    return conteo


def top_palabras(conteo: dict[str, int], n: int = 5) -> list[tuple[str, int]]:
    """Devuelve las n palabras más frecuentes, de mayor a menor."""
    ranking = sorted(conteo.items(), key=lambda par: par[1], reverse=True)
    return ranking[:n]


texto = (
    "el almacén guarda cajas el almacén ordena cajas el gerente cuenta cajas"
)

conteo = contar_palabras(texto)
for palabra, veces in top_palabras(conteo):
    print(f"{veces:>3}  {palabra}")

Lleva más Lejos

  • Lee el texto de un archivo real con Path("documento.txt").read_text(encoding="utf-8").
  • Ignora palabras vacías como “el”, “y”, “de” (las llaman stop words): guárdalas en un set y sáltalas con continue.
  • Guarda el conteo en un conteo.json con json.dump, para no recalcularlo cada vez.

Cada mejora reutiliza algo que ya sabes. Eso es construir sobre tus propios cimientos.