Programación · n.º 4 entre los lenguajes más usados

Aprende Python desde cero

Fácil de leer y válido para casi todo: automatizar tareas, datos e inteligencia artificial.

  • 15 lecciones
  • 19 ejercicios interactivos
  • 25 conceptos clave
  • 58 % lo usa*

Qué es Python y para qué sirve

Python se lee casi como inglés y tiene bibliotecas para todo, por eso es uno de los lenguajes más recomendados para empezar. Se usa para automatizar tareas repetitivas, analizar datos, crear webs y en casi todo lo relacionado con la inteligencia artificial.

  • Automatizar tareas y scripts
  • Análisis de datos e inteligencia artificial
  • Webs y APIs

Para empezar: Instala Python desde python.org, abre la terminal y escribe python (o py en Windows) para probar los ejemplos.

Nivel 1 Básico

Lección 1 · Básico

Tu primer programa

Python se ejecuta con un intérprete: lee tu código línea a línea y lo ejecuta. Puedes escribir órdenes directamente en él o guardarlas en un archivo .py y ejecutarlo con python archivo.py.

print() muestra en pantalla lo que le pases. Los comentarios empiezan por #.

Ejemplo práctico
# hola.py
print("¡Hola, mundo!")
print(2 + 3)      # 5
print(10 / 4)     # 2.5

Ejercicio

Completa para mostrar «Hola» en pantalla.

("Hola")
Ver la solución

Respuesta: print. print() escribe en la salida lo que pongas entre paréntesis.

Lección 2 · Básico

Variables, tipos y texto

Una variable se crea al darle un valor con =; no hace falta declarar su tipo. Los tipos básicos son int (enteros), float (decimales), str (texto) y bool (True o False).

input() pide un texto a la persona y siempre devuelve str: para hacer cuentas, conviértelo con int() o float(). Las cadenas f (f"…{variable}…") meten valores dentro de un texto.

Ejemplo práctico
nombre = input("¿Cómo te llamas? ")
edad = int(input("¿Cuántos años tienes? "))

print(f"Hola, {nombre}. El año que viene tendrás {edad + 1}.")
print(type(edad))   # <class 'int'>

Ejercicio

¿Qué tipo de dato devuelve siempre input()?

Ver la solución

Respuesta: str. input() devuelve texto (str); para operar con números hay que convertirlo.

Lección 3 · Básico

Condiciones y sangría

if, elif y else deciden qué bloque se ejecuta. En Python los bloques no van entre llaves: se marcan con dos puntos al final de la línea y con sangría (4 espacios) en las de dentro.

Si la sangría no es coherente, Python da un error. Es una regla del lenguaje, no una cuestión de estilo.

Ejemplo práctico
nota = 7.5

if nota >= 9:
    print("Sobresaliente")
elif nota >= 5:
    print("Aprobado")
else:
    print("Suspenso")
# Muestra: Aprobado

Ejercicio

¿Cómo marca Python qué líneas van dentro de un if?

Ver la solución

Respuesta: Con la sangría. Las líneas del bloque van sangradas (normalmente 4 espacios) tras los dos puntos.

Encuentra los errores

Este programa debería decir «Sobresaliente» con un 9 o más, «Aprobado» con un 5 o más y «Suspenso» con menos. Python lo rechaza por 2 errores: márcalos.

Ver la solución
  • Línea 3: Las líneas con if, elif y else terminan con dos puntos :. Corrección: if nota >= 9:
  • Línea 6: El bloque del elif tiene que ir con sangría (4 espacios); si no, Python da IndentationError. Corrección: print("Aprobado")

Lección 4 · Básico

Listas y bucles

Una lista guarda varios valores en orden entre corchetes; la primera posición es la 0. Con append() añades al final y len() te dice cuántos elementos tiene.

for recorre cada elemento de una lista, y range(n) genera los números de 0 a n−1 cuando necesitas repetir algo un número fijo de veces.

Ejemplo práctico
compra = ["pan", "leche"]
compra.append("huevos")
print(len(compra))  # 3

for producto in compra:
    print("- " + producto)

for i in range(3):
    print(i)        # 0, 1 y 2

Ejercicio

¿Qué números genera range(3)?

Ver la solución

Respuesta: 0, 1, 2. range(n) empieza en 0 y se detiene antes de n.

Escribe el código

Escribe la función contar_mayores(numeros, limite): devuelve cuántos números de la lista son mayores que limite. Usa un bucle for y un contador.

Tab escribe una sangría; para salir del editor con el teclado, pulsa Esc y luego Tab. Ctrl + Intro corrige.

Ver la solución
def contar_mayores(numeros, limite):
    contador = 0
    for n in numeros:
        if n > limite:
            contador += 1
    return contador

El contador empieza en 0 y sube cada vez que un número supera el límite. «Mayor que» excluye el propio límite: con 5, el 5 no cuenta.

Nivel 2 Intermedio

Lección 5 · Intermedio

Funciones

Con def defines una función: un nombre, sus parámetros entre paréntesis y el bloque sangrado. return devuelve el resultado.

Los parámetros pueden tener un valor por defecto, que se usa si no lo pasas al llamar a la función.

Ejemplo práctico
def precio_final(precio, iva=21):
    return round(precio * (1 + iva / 100), 2)

print(precio_final(100))       # 121.0
print(precio_final(100, 10))   # 110.0

Ejercicio

Completa la palabra que define una función.

 saludar(nombre):
    return "Hola, " + nombre
Ver la solución

Respuesta: def. Las funciones se definen con def nombre(parámetros):.

Escribe el código

Escribe es_palindromo(texto): devuelve True si el texto se lee igual del derecho y del revés, sin tener en cuenta los espacios ni las mayúsculas («Ana», «Anita lava la tina»), y False si no.

Tab escribe una sangría; para salir del editor con el teclado, pulsa Esc y luego Tab. Ctrl + Intro corrige.

Ver la solución
def es_palindromo(texto):
    limpio = texto.replace(" ", "").lower()
    return limpio == limpio[::-1]

replace(" ", "") quita los espacios, lower() pasa todo a minúsculas y [::-1] le da la vuelta al texto. Si coincide con el original, es un palíndromo.

Conceptos clave

Lección 6 · Intermedio

Diccionarios

Un diccionario guarda pares clave–valor entre llaves: perfecto para describir algo con varios datos o para contar cosas. Accedes a un valor con su clave entre corchetes.

.get(clave, por_defecto) evita el error si la clave no existe, e .items() recorre las parejas.

Ejemplo práctico
stock = {"teclado": 10, "raton": 0}
stock["monitor"] = 3

print(stock["teclado"])          # 10
print(stock.get("webcam", 0))    # 0, sin error

for producto, unidades in stock.items():
    print(producto, unidades)

Ejercicio

¿Qué pasa con stock["webcam"] si esa clave no existe?

Ver la solución

Respuesta: Da un error KeyError. Con corchetes, una clave inexistente lanza KeyError; con .get() puedes dar un valor por defecto.

Encuentra los errores

Este programa guarda el stock de una frutería y debería mostrar True y después False. Tiene 2 errores.

Ver la solución
  • Línea 4: stock[producto] da KeyError si el producto no está en el diccionario, como los kiwis. get() devuelve un valor por defecto. Corrección: return stock.get(producto, 0) > 0
  • Línea 6: == compara y descarta el resultado; para añadir la clave hay que asignar con un solo =. Corrección: stock["platanos"] = 12

Lección 7 · Intermedio

Archivos y errores

open() abre un archivo; dentro de un bloque with, Python lo cierra solo al terminar, aunque haya un error. Indica siempre la codificación utf-8 para que las tildes se lean bien.

Los errores en tiempo de ejecución son excepciones. Con try y except las capturas y decides qué hacer en lugar de que el programa se detenga.

Ejemplo práctico
try:
    with open("notas.txt", encoding="utf-8") as f:
        for linea in f:
            print(linea.strip())
except FileNotFoundError:
    print("No encuentro notas.txt")

Ejercicio

¿Qué ventaja tiene abrir un archivo con with?

Ver la solución

Respuesta: El archivo se cierra solo al terminar. with garantiza que el archivo se cierra al salir del bloque, también si ocurre un error.

Nivel 3 Avanzado

Lección 8 · Avanzado

Módulos, pip y entornos virtuales

Python trae una gran biblioteca estándar que usas con import. Para todo lo demás está PyPI, el repositorio de paquetes, y pip, que los instala.

Crea un entorno virtual por proyecto (python -m venv .venv) para que cada uno tenga sus propias versiones de bibliotecas y no choquen entre sí.

Ejemplo práctico
# En la terminal
python -m venv .venv
# Windows:  .venv\Scripts\activate
# macOS/Linux:  source .venv/bin/activate
pip install requests

# En tu programa
import json
from datetime import date

print(date.today().isoformat())
print(json.dumps({"ok": True}))

Ejercicio

Completa el comando que instala un paquete de PyPI.

 install requests
Ver la solución

Respuesta: pip. pip install paquete descarga e instala una biblioteca en el entorno activo.

Lección 9 · Avanzado

Clases y objetos

Una clase es un molde para crear objetos que tienen datos (atributos) y acciones (métodos). __init__ se ejecuta al crear cada objeto y self es el propio objeto.

Las clases ayudan a ordenar programas grandes agrupando los datos con el código que trabaja con ellos.

Ejemplo práctico
class Cuenta:
    def __init__(self, titular, saldo=0):
        self.titular = titular
        self.saldo = saldo

    def ingresar(self, cantidad):
        if cantidad <= 0:
            raise ValueError("La cantidad debe ser positiva")
        self.saldo += cantidad

cuenta = Cuenta("Ana")
cuenta.ingresar(50)
print(cuenta.saldo)   # 50

Ejercicio

¿Qué método se ejecuta automáticamente al crear un objeto?

Ver la solución

Respuesta: __init__. __init__ prepara el objeto nuevo: normalmente guarda los valores iniciales en self.

Lección 10 · Avanzado

Comprensiones y anotaciones de tipo

Una lista por comprensión crea una lista nueva a partir de otra en una sola línea: [expresión for x in lista if condición].

Las anotaciones de tipo (precio: float) documentan qué espera y devuelve cada función. Python no las comprueba al ejecutar, pero el editor y herramientas como mypy sí te avisan de errores.

Ejemplo práctico
precios = [3.5, 12.0, 0.99, 25.0]

caros = [p for p in precios if p > 10]
print(caros)   # [12.0, 25.0]

def media(valores: list[float]) -> float:
    return sum(valores) / len(valores)

print(media(precios))   # 10.3725

Ejercicio

¿Qué devuelve [n * 2 for n in [1, 2, 3]]?

Ver la solución

Respuesta: [2, 4, 6]. La comprensión aplica n * 2 a cada elemento y junta los resultados en una lista nueva.

Lección 11 · Avanzado

Lanzar tus propios errores con raise

Además de capturar errores con try y except, puedes lanzarlos con raise cuando una función recibe algo que no tiene sentido. Así el fallo aparece en el momento y en el sitio donde ocurre, en lugar de arrastrar un dato erróneo.

Para errores propios de tu programa, crea una clase que herede de Exception. Quien llame a la función puede capturar justo ese tipo de error y darle un mensaje claro a la persona.

Ejemplo práctico
class SaldoInsuficiente(Exception):
    pass

def retirar(saldo, cantidad):
    if cantidad <= 0:
        raise ValueError("La cantidad tiene que ser positiva")
    if cantidad > saldo:
        raise SaldoInsuficiente(f"Faltan {cantidad - saldo} €")
    return saldo - cantidad

print(retirar(100, 30))  # 70

try:
    retirar(100, 150)
except SaldoInsuficiente as error:
    print("No se puede retirar:", error)  # No se puede retirar: Faltan 50 €

Escribe el código

Escribe leer_edad(texto): convierte el texto en un número entero y lo devuelve. Si el número es negativo o mayor que 130, lanza un ValueError con raise. (Si el texto no es un número, int() ya lanza ValueError por sí solo.)

Tab escribe una sangría; para salir del editor con el teclado, pulsa Esc y luego Tab. Ctrl + Intro corrige.

Ver la solución
def leer_edad(texto):
    edad = int(texto)
    if edad < 0 or edad > 130:
        raise ValueError("Edad fuera de rango")
    return edad

int(texto) convierte el texto; después se comprueba el rango y, si no es válido, raise ValueError(...) detiene la función con ese error.

Lección 12 · Avanzado

Datos en JSON y CSV

JSON y CSV son los formatos más habituales para guardar e intercambiar datos. El módulo json convierte diccionarios y listas en texto JSON (json.dumps) y al revés (json.loads); json.dump y json.load hacen lo mismo directamente con un archivo.

El módulo csv lee y escribe tablas separadas por comas, como las que abre una hoja de cálculo. csv.DictReader devuelve cada fila como un diccionario cuyas claves son los títulos de la primera fila. Abre los archivos con encoding="utf-8" para que las tildes se lean bien.

Ejemplo práctico
import csv
import json

with open("gastos.csv", "w", newline="", encoding="utf-8") as f:
    f.write("concepto,importe\nLuz,45.20\nAgua,18.75\nInternet,30\n")

with open("gastos.csv", newline="", encoding="utf-8") as f:
    filas = list(csv.DictReader(f))

total = sum(float(fila["importe"]) for fila in filas)
print(f"{len(filas)} gastos, total: {total:.2f} €")  # 3 gastos, total: 93.95 €

resumen = {"gastos": len(filas), "total": round(total, 2)}
print(json.dumps(resumen))  # {"gastos": 3, "total": 93.95}

Ejercicio

Completa para convertir el texto JSON en un diccionario de Python.

datos = json.('{"nombre": "Ana"}')
Ver la solución

Respuesta: loads. json.loads() convierte un texto JSON en diccionarios y listas de Python; json.dumps() hace lo contrario.

Lección 13 · Avanzado

Fechas y horas con datetime

El módulo datetime representa fechas (date), fechas con hora (datetime) y duraciones (timedelta). Restar dos fechas da un timedelta, y sumar un timedelta a una fecha la mueve hacia delante o hacia atrás.

strftime convierte una fecha en texto con el formato que quieras (%d/%m/%Y es día/mes/año) y strptime hace lo contrario: lee un texto con ese formato y lo convierte en fecha.

Ejemplo práctico
from datetime import date, datetime, timedelta

inicio = date(2026, 1, 15)
fin = date(2026, 3, 1)
print((fin - inicio).days)                  # 45

entrega = inicio + timedelta(days=30)
print(entrega.strftime("%d/%m/%Y"))        # 14/02/2026

cita = datetime.strptime("25/12/2026 18:30", "%d/%m/%Y %H:%M")
print(cita.year, cita.hour, cita.minute)    # 2026 18 30
print(cita.weekday())                       # 4 (lunes es 0: es viernes)

Ejercicio

¿Qué devuelve date(2026, 3, 1) - date(2026, 2, 1)?

Ver la solución

Respuesta: Un timedelta de 28 días. Restar dos fechas da un timedelta (una duración); su atributo .days vale 28, porque febrero de 2026 tiene 28 días.

Lección 14 · Avanzado

Generadores: valores de uno en uno con yield

Una función con yield es un generador: en lugar de devolver todos los resultados de golpe en una lista, entrega un valor cada vez que se le pide y se queda en pausa hasta el siguiente. Se recorre con for igual que una lista.

Como no guarda todos los valores a la vez, un generador puede recorrer archivos enormes o secuencias muy largas usando muy poca memoria. Si necesitas la lista completa, list(generador) la crea.

Ejemplo práctico
def cuenta_atras(desde):
    while desde > 0:
        yield desde
        desde -= 1

for n in cuenta_atras(3):
    print(n)          # 3, 2 y 1, cada uno en una línea

def lineas_largas(lineas, minimo):
    for linea in lineas:
        if len(linea) >= minimo:
            yield linea.strip()

texto = ["hola\n", "esta línea es larga\n", "fin\n"]
print(list(lineas_largas(texto, 10)))  # ['esta línea es larga']

Escribe el código

Escribe el generador pares(limite): entrega con yield, uno a uno, los números pares desde 0 hasta limite sin incluirlo.

Tab escribe una sangría; para salir del editor con el teclado, pulsa Esc y luego Tab. Ctrl + Intro corrige.

Ver la solución
def pares(limite):
    n = 0
    while n < limite:
        yield n
        n += 2

Con while o con range(0, limite, 2), cada yield entrega un número y la función continúa por donde iba la siguiente vez.

Lección 15 · Avanzado

Pruebas automáticas con unittest

Una prueba automática es código que comprueba que otro código hace lo que debe. Si cambias algo y rompes una función, la prueba falla y te avisa antes de que lo note nadie. Python trae el módulo unittest para escribirlas.

Cada prueba es un método que empieza por test dentro de una clase que hereda de unittest.TestCase, y usa comprobaciones como assertEqual o assertRaises. Se ejecutan todas con python -m unittest.

Ejemplo práctico
import unittest

def precio_final(precio, descuento):
    if not 0 <= descuento <= 100:
        raise ValueError("El descuento va de 0 a 100")
    return round(precio * (1 - descuento / 100), 2)

class PruebasPrecio(unittest.TestCase):
    def test_sin_descuento(self):
        self.assertEqual(precio_final(50, 0), 50)

    def test_con_descuento(self):
        self.assertEqual(precio_final(80, 25), 60)

    def test_descuento_imposible(self):
        with self.assertRaises(ValueError):
            precio_final(10, 120)

if __name__ == "__main__":
    unittest.main()  # Ran 3 tests ... OK

Encuentra los errores

Estas pruebas deberían comprobar es_par(n), pero tienen 2 errores: una no se ejecutaría nunca y otra espera un resultado equivocado.

Ver la solución
  • Línea 10: unittest solo ejecuta los métodos cuyo nombre empieza por test; este se ignoraría sin avisar. Corrección: def test_siete(self):
  • Línea 14: 0 es par (0 % 2 vale 0), así que es_par(0) devuelve True y la prueba fallaría aunque la función esté bien. Corrección: self.assertEqual(es_par(0), True)

¿Has terminado? Sigue practicando

Repasa los conceptos en el diccionario, practica con estas herramientas o prueba otro lenguaje: las ideas que has aprendido (variables, condiciones, funciones, objetos…) te servirán en cualquiera.

Proyectos para practicar Python

  • Texto y programación

    Probador de expresiones regulares

    Prueba una expresión regular sobre tu texto, con coincidencias, grupos y explicación en español.

  • Texto y programación

    Base64, URL y JSON

    Codifica y decodifica Base64 y URL, y valida o formatea JSON con la línea del error.

  • Texto y programación

    Comparar dos textos

    Encuentra las diferencias entre dos versiones de un texto, línea a línea y palabra a palabra.

Fuentes consultadas

* Porcentaje de personas que dijeron haber usado Python en la Stack Overflow Developer Survey 2026: Technology (pregunta sobre lenguajes de programación, de scripts y de marcado; todas las respuestas). El progreso de las lecciones se guarda solo en este navegador.