La forma más rápida de aprender a programar no es mirar más videos: es resolver problemas pequeños, equivocarte y entender por qué. Esta guía reúne doce ejercicios de lógica en Python ordenados por dificultad, cada uno con su solución comentada y, más importante, con la explicación de qué conceptos entrena. Están pensados para quien ya vio variables, condiciones y bucles, y todavía no sabe cómo practicar.
La recomendación es simple: dedica entre 20 y 40 minutos al día, intenta cada ejercicio al menos diez minutos antes de leer la solución, y escribe el código a mano en lugar de copiarlo. Si copias y pegás, el cerebro no registra nada; si escribes, los dedos aprenden la sintaxis y los ojos detectan los errores.
Cómo usar esta lista (y cómo no usarla)
Antes de empezar, tres reglas que hacen la diferencia entre practicar y perder el tiempo:
- Escribe la solución primero en papel. Describir los pasos en español antes de escribir código reduce la mitad de los errores de lógica.
- Prueba con el caso más simple. Un número, una palabra, una lista de dos elementos. Si funciona con dos, probablemente funcione con doscientos.
- Lee la solución solo después de intentarlo. Y cuando la leas, cierra el archivo y vuelve a escribirla de memoria.
Las soluciones que ves abajo no son las únicas correctas. Si tu versión funciona y se entiende, está bien.
Bloque 1: variables, condiciones y bucles
Ejercicio 1 — Conversor de temperatura
Pide una temperatura en grados Celsius e imprime su equivalente en Fahrenheit.
celsius = float(input("Temperatura en Celsius: "))
fahrenheit = celsius * 9 / 5 + 32
print(f"{celsius} °C equivalen a {fahrenheit:.1f} °F")
Entrena: entrada de datos, conversión de tipos, formato de decimales.
Ejercicio 2 — Clasificador de números
Dado un número entero, indica si es positivo, negativo o cero, y si es par o impar.
numero = int(input("Escribe un número entero: "))
if numero > 0:
signo = "positivo"
elif numero < 0:
signo = "negativo"
else:
signo = "cero"
if numero == 0:
paridad = "no aplica"
elif numero % 2 == 0:
paridad = "par"
else:
paridad = "impar"
print(f"El número es {signo} y {paridad}.")
Entrena: condicionales encadenados y el operador módulo, que vas a usar muchísimo para validar datos.
Ejercicio 3 — Tabla de multiplicar con validación
Pide un número entre 1 y 10 y muestra su tabla de multiplicar. Si el número está fuera de rango, avisa y no continúa.
numero = int(input("Número entre 1 y 10: "))
if not 1 <= numero <= 10:
print("El número está fuera de rango.")
else:
for i in range(1, 11):
print(f"{numero} x {i} = {numero * i}")
Entrena: rango con range, validación temprana y salida anticipada.
Ejercicio 4 — Suma acumulada hasta cero
Suma números que el usuario ingresa hasta que escriba 0. Al final muestra el total y cuántos números válidos se sumaron.
total = 0
cantidad = 0
while True:
valor = float(input("Número (0 para terminar): "))
if valor == 0:
break
total += valor
cantidad += 1
print(f"Sumaste {cantidad} números. Total: {total}")
Entrena: bucle con condición de corte, acumuladores y la diferencia entre break y terminar la condición del while.
Bloque 2: listas y diccionarios
Ejercicio 5 — Promedio, máximo y mínimo sin funciones mágicas
Dada una lista de notas, calcula el promedio y encuentra la mayor y la menor sin usar max() ni min().
notas = [7, 4, 9, 6, 10, 3]
suma = 0
mayor = notas[0]
menor = notas[0]
for nota in notas:
suma += nota
if nota > mayor:
mayor = nota
if nota < menor:
menor = nota
promedio = suma / len(notas)
print(f"Promedio: {promedio:.2f} | Mayor: {mayor} | Menor: {menor}")
Entrena: recorrido de listas, comparación acumulativa y el patrón "inicializar con el primer elemento".
Ejercicio 6 — Contar palabras repetidas
Dada una frase, indica cuántas veces aparece cada palabra.
frase = "aprender python requiere practicar y practicar"
conteo = {}
for palabra in frase.lower().split():
conteo[palabra] = conteo.get(palabra, 0) + 1
for palabra, veces in sorted(conteo.items(), key=lambda par: -par[1]):
print(f"{palabra}: {veces}")
Entrena: diccionarios como contadores, dict.get con valor por defecto y ordenamiento por clave secundaria.
Ejercicio 7 — Filtrar y transformar en una línea
De una lista de precios, genera una nueva lista solo con los precios mayores a 1000, aplicándoles un 10% de descuento.
precios = [500, 1500, 3200, 800, 4500]
con_descuento = [precio * 0.9 for precio in precios if precio > 1000]
print(con_descuento)
Entrena: comprensión de listas. Es el mismo resultado que un for con append, pero más corto y más usado en código real.
Ejercicio 8 — Diccionario de inventario
Representa un inventario como diccionario y responde: ¿cuál es el producto más caro?, ¿cuál es el valor total del stock?
inventario = {
"teclado": {"precio": 25000, "cantidad": 4},
"mouse": {"precio": 12000, "cantidad": 10},
"monitor": {"precio": 180000, "cantidad": 2},
}
mas_caro = max(inventario, key=lambda nombre: inventario[nombre]["precio"])
valor_total = sum(datos["precio"] * datos["cantidad"] for datos in inventario.values())
print(f"Más caro: {mas_caro} | Valor del stock: {valor_total}")
Entrena: estructuras anidadas, max con función clave y generadores.
Bloque 3: funciones, archivos y errores
Ejercicio 9 — Función con validación
Escribe una función que reciba una edad y devuelva True si es mayor de edad, lanzando un error si el valor es negativo.
def es_mayor_de_edad(edad):
if edad < 0:
raise ValueError("La edad no puede ser negativa")
return edad >= 18
print(es_mayor_de_edad(20)) # True
print(es_mayor_de_edad(15)) # False
Entrena: funciones puras, validación y excepciones. Una función que recibe datos inválidos debería fallar rápido y con un mensaje claro.
Ejercicio 10 — Leer un archivo y contar líneas
Lee un archivo de texto y muestra cuántas líneas tiene y cuántas están vacías.
with open("notas.txt", encoding="utf-8") as archivo:
lineas = archivo.readlines()
vacias = sum(1 for linea in lineas if not linea.strip())
print(f"Líneas totales: {len(lineas)} | Vacías: {vacias}")
Entrena: manejo de archivos con with, codificación explícita y comprensiones sobre generadores.
Ejercicio 11 — Guardar resultados en JSON
Toma una lista de diccionarios y guárdala en un archivo JSON. Luego vuelve a leerla y muestra el primer registro.
import json
registros = [
{"nombre": "Ana", "horas": 12},
{"nombre": "Luis", "horas": 8},
]
with open("horas.json", "w", encoding="utf-8") as archivo:
json.dump(registros, archivo, ensure_ascii=False, indent=2)
with open("horas.json", encoding="utf-8") as archivo:
recuperados = json.load(archivo)
print(recuperados[0])
Entrena: serialización, codificación de caracteres y el ciclo guardar-leer que está detrás de casi toda automatización.
Ejercicio 12 — Mini reporte de horas
Combina todo lo anterior: lee la lista del ejercicio 11, suma las horas y muestra quién trabajó más y el promedio.
import json
with open("horas.json", encoding="utf-8") as archivo:
registros = json.load(archivo)
total = sum(registro["horas"] for registro in registros)
promedio = total / len(registros)
maximo = max(registros, key=lambda registro: registro["horas"])
print(f"Total: {total} h | Promedio: {promedio:.1f} h | Más horas: {maximo['nombre']}")
Entrena: composición de lo aprendido. Este ejercicio es, en miniatura, el trabajo real de un analista o automatizador.
Ejemplo trabajado: de cero a un reporte útil
Veamos cómo se combinan los ejercicios 10, 11 y 12 en un caso concreto: tienes tres archivos de texto con las horas que registró cada persona del equipo y necesitas un único reporte con totales por persona.
# entrada: horas_ana.txt
# formato: una entrada por línea "fecha,horas"
2026-09-01,4
2026-09-02,6
El programa completo:
import json
from pathlib import Path
def leer_horas(archivo: Path) -> int:
total = 0
with archivo.open(encoding="utf-8") as f:
for linea in f:
linea = linea.strip()
if not linea:
continue
_, horas = linea.split(",")
total += float(horas)
return total
registros = []
for archivo in sorted(Path(".").glob("horas_*.txt")):
persona = archivo.stem.replace("horas_", "")
registros.append({"persona": persona, "total": leer_horas(archivo)})
suma = sum(registro["total"] for registro in registros)
promedio = suma / len(registros) if registros else 0
print(f"{'Persona':10} {'Horas':>7}")
for registro in registros:
print(f"{registro['persona']:10} {registro['total']:>7.1f}")
print(f"{'TOTAL':10} {suma:>7.1f} (promedio {promedio:.1f})")
Lo importante no es el código, sino las decisiones: qué hacer con las líneas vacías, cómo derivar el nombre de la persona desde el archivo y qué pasa si un archivo está vacío. Ese tipo de preguntas es exactamente lo que separa a quien escribe código de quien resuelve problemas.
Cómo verificar tus respuestas sin depender de nadie
- Usa
assert.assert calcular_promedio([2, 4]) == 3te avisa al instante si rompiste algo. - Prueba los bordes. Lista vacía, un solo elemento, valores negativos, texto con tildes.
- Imprime el estado intermedio. Un
printbien ubicado explica más que una hora de lectura del error. - Explica tu solución en voz alta. Si no puedes explicarla, todavía no la entendiste.
Limitaciones: cuándo estos ejercicios no son suficientes
Doce ejercicios no te convierten en programador, del mismo modo que doce partidos de fútbol no te convierten en profesional. Después de este bloque vas a poder escribir lógica básica, pero te faltan tres cosas que solo se aprenden construyendo algo real:
- Estructura de un proyecto. Separar código en módulos, manejar dependencias, escribir un README.
- Datos sucios. En el ejercicio todo funciona; en la vida real faltan columnas, hay fechas inválidas y textos inconsistentes.
- Pruebas y control de versiones. Son hábitos, no temas, y se incorporan cuando el proyecto empieza a crecer.
La progresión sana es: ejercicios pequeños, después un proyecto que te interese de verdad y, en paralelo, aprender a usar Git.
Preguntas frecuentes
¿Qué hago si no me sale ningún ejercicio? Baja un nivel: copia la solución, ciérrala y reescríbela sin mirar. Si aún así no sale, el problema es de sintaxis, y toca repasar condicionales o bucles antes de seguir.
¿Cuánto tiempo por ejercicio? Entre 10 y 30 minutos. Si un ejercicio te lleva una hora, probablemente estés resolviendo algo más avanzado de lo que necesitas ahora.
¿Necesito saber matemáticas? Solo aritmética y proporciones. La programación pide lógica, no cálculo.
¿Sirve Python si después quiero hacer frontend? Sí: los conceptos (variables, funciones, listas) son transferibles. Después aprenderás la sintaxis de JavaScript en semanas.
¿Puedo usar IA para que me corrija? Sí, pero pídele que te explique el error, no que te dé el código. La corrección que no entiendes no se convierte en aprendizaje.
¿Con qué sigo después? Con un proyecto propio pequeño: una calculadora de gastos, un renombrador de archivos o un reporte automático. Cualquiera de los tres te obliga a combinar lo aprendido.
Siguiente paso
Si quieres una ruta ordenada, el temario de Python para principiantes continúa esta progresión con módulos y un mini proyecto. También puedes revisar los recursos gratuitos para aprender programación y la categoría Aprender IA. Y si preferís practicar con acompañamiento y revisión de tus ejercicios, mira los cursos de Cursalo y sus precios.
