Aprende Python desde cero
Una guía para aprender a programar en Python, aunque nunca hayas escrito una línea de código. Cada lección explica una idea con palabras simples y trae ejemplos que puedes ejecutar y modificar aquí mismo, un ejercicio para practicar y una pregunta para comprobar que lo entendiste.
for i in range(1, 4): print(f"Lección {i}: ¡hecha!") Lección 1: ¡hecha! Lección 2: ¡hecha! Lección 3: ¡hecha!
Antes de empezar
Objetivo: entender qué es programar, ejecutar tu primer código y aprender a leer un error.
Programar es escribir instrucciones para que la computadora las siga, una por una y en orden. Python es uno de los lenguajes más usados para eso porque se lee casi como inglés. Con él se hacen páginas web, se automatizan tareas aburridas, se analizan datos y se crea inteligencia artificial.
Dónde escribir Python
| Opción | Para quién |
|---|---|
| Esta misma página | Para empezar ya. Pulsa ▶ Ejecutar en cualquier ejemplo. La primera vez tarda unos segundos en cargar. |
| Google Colab | Gratis, en el navegador, con cuenta de Google. Ideal para practicar y guardar tus cuadernos. |
| python.org + VS Code | Para programar en tu computadora. Al instalar Python en Windows, marca la casilla “Add python.exe to PATH”. |
Tu primer programa
print("¡Hola, mundo!")¡Hola, mundo!
print() es una función: una orden con nombre que hace algo. Lo que pones entre los paréntesis es lo que se muestra. El texto va entre comillas.
print("Estoy aprendiendo Python")
print(2026)
print("Mi edad es", 20) # print acepta varias cosas separadas por comaEstoy aprendiendo Python 2026 Mi edad es 20
Todo lo que va después de # es un comentario: Python lo ignora. Úsalos para explicar tu código.
Leer un error (sin miedo)
Los errores son normales: los programadores con experiencia los ven todo el día. Lo importante es leerlos. Ejecuta esto:
nombre = "Ana"
print(nombe)Traceback (most recent call last):
File "main.py", line 2, in <module>
print(nombe)
^^^^^
NameError: name 'nombe' is not defined. Did you mean: 'nombre'?Léelo de abajo hacia arriba. La última línea dice qué pasó (NameError: ese nombre no existe) e incluso sugiere la solución: quizás quisiste escribir nombre. Las líneas de arriba dicen dónde: línea 2. Corrígelo con Editar y ejecútalo de nuevo.
Aparece un error largo en pantalla. ¿Por dónde empiezas a leerlo?
Variables y tipos de datos
Objetivo: guardar información con un nombre y conocer los cuatro tipos de datos básicos.
Una variable es un nombre que guarda un valor. Se crea con =, que en Python no significa “es igual a”, sino “guarda esto aquí”.
nombre = "Ana" # texto (str)
edad = 20 # número entero (int)
altura = 1.65 # número decimal (float)
estudiante = True # verdadero/falso (bool)
print(nombre, edad, altura, estudiante)Ana 20 1.65 True
edad = 20 es “mete el 20 en una caja llamada edad”. Después escribes edad y Python saca lo que hay dentro.| Tipo | Qué guarda | Ejemplo |
|---|---|---|
str | Texto, entre comillas | "Ana", 'hola' |
int | Números enteros | 20, -3 |
float | Números con decimales (con punto) | 1.65 |
bool | Verdadero o falso | True, False |
Con type() preguntas de qué tipo es algo:
print(type(nombre))
print(type(edad))
print(type(altura))
print(type(estudiante))<class 'str'> <class 'int'> <class 'float'> <class 'bool'>
Convertir entre tipos
print(int("25") + 5) # texto -> entero
print(float("3.5") * 2) # texto -> decimal
print(str(100) + " puntos") # número -> texto
print(int(7.9)) # int() corta los decimales, no redondea
print(round(7.9)) # round() sí redondea30 7.0 100 puntos 7 8
Las variables cambian
x = 5
print(x)
x = x + 1 # toma el valor actual, le suma 1 y lo guarda de nuevo
print(x)
x = "cinco" # una variable puede cambiar de tipo
print(x)5 6 cinco
Reglas para los nombres: letras, números y _, sin espacios, sin empezar con número. Python distingue mayúsculas: Edad y edad son distintas. La costumbre es usar minúsculas con guion bajo: precio_total.
Ver solución
producto = "Cuaderno"
precio = 3.5
cantidad = 4
total = precio * cantidad
print("Producto:", producto)
print("Total a pagar:", total)Producto: Cuaderno Total a pagar: 14.0
¿De qué tipo es "42"?
Operadores
Objetivo: hacer cuentas, comparar valores y combinar condiciones.
Aritméticos
print(7 + 2) # suma
print(7 - 2) # resta
print(7 * 2) # multiplicación
print(7 / 2) # división (siempre da decimal)
print(7 // 2) # división entera
print(7 % 2) # resto (módulo)
print(7 ** 2) # potencia9 5 14 3.5 3 1 49
// y % son más útiles de lo que parecen: % te dice si un número es par (n % 2 == 0) y, junto con //, sirve para convertir minutos en horas.
print(2 + 3 * 4) # primero la multiplicación
print((2 + 3) * 4) # los paréntesis mandan14 20
**, no ^. Y el decimal se escribe con punto: 3.5. Con coma, 3,5 son dos números distintos.De comparación: dan True o False
print(5 > 3)
print(5 == 5.0) # == compara; = asigna
print(3 != 3)
print("a" < "b") # los textos se comparan en orden alfabéticoTrue True False True
Lógicos: and, or, not
edad = 20
tiene_entrada = False
print(edad >= 18 and tiene_entrada) # and: las dos deben ser verdad
print(edad >= 18 or tiene_entrada) # or: basta con una
print(not tiene_entrada) # not: invierteFalse True True
Asignación abreviada
puntos = 10
puntos += 5 # igual que: puntos = puntos + 5
puntos *= 2 # igual que: puntos = puntos * 2
puntos -= 3
print(puntos)27
Ver una pista
Un número es par si el resto de dividirlo entre 2 es 0. Para las horas usa // y para los minutos sobrantes, %.
Ver solución
numero = 17
print(numero % 2 == 0) # ¿es par?
minutos = 135
print(minutos // 60, "horas y", minutos % 60, "minutos")False 2 horas y 15 minutos
¿Cuánto da 2 + 3 * 4?
Texto (strings)
Objetivo: recortar, transformar y armar textos.
Posiciones: se cuenta desde 0
palabra = "Python"
print(palabra[0]) # primera letra (se cuenta desde 0)
print(palabra[-1]) # última letra
print(palabra[0:3]) # de la 0 a la 2 (el 3 no se incluye)
print(palabra[::-1]) # al revés
print(len(palabra)) # longitudP n Pyt nohtyP 6
[0]. En un rango [0:3] se incluye el inicio pero no el final. Los números negativos cuentan desde el final.Métodos: acciones que el texto sabe hacer
Un método se escribe con un punto después del valor: texto.upper().
frase = " Aprender Python es divertido "
print(frase.strip()) # quita espacios de los extremos
print(frase.upper()) # mayúsculas
print(frase.lower()) # minúsculas
print(frase.replace("divertido", "útil"))
print(frase.split()) # separa en una lista de palabras
print(frase.count("e")) # cuántas veces aparece "e"Aprender Python es divertido APRENDER PYTHON ES DIVERTIDO aprender python es divertido Aprender Python es útil ['Aprender', 'Python', 'es', 'divertido'] 4
f-strings: meter variables en un texto
Pon una f antes de las comillas y escribe las variables entre llaves { }.
nombre = "Ana"
edad = 20
print(f"Me llamo {nombre} y tengo {edad} años")
print(f"El próximo año tendré {edad + 1}")
precio = 1234.5678
print(f"{precio:.2f}") # 2 decimales
print(f"{precio:,.2f}") # con separador de miles
print(f"{0.256:.1%}") # como porcentajeMe llamo Ana y tengo 20 años El próximo año tendré 21 1234.57 1,234.57 25.6%
Más operaciones
print("Py" in "Python")
print("java" in "Python")
print("-".join(["a", "b", "c"])) # une una lista con un separador
print("Ja" * 3) # repetir textoTrue False a-b-c JaJaJa
palabra = "Python"
try:
palabra[0] = "J"
except TypeError as error:
print("Error:", error)
palabra = "J" + palabra[1:] # en su lugar, se crea un texto nuevo
print(palabra)Error: 'str' object does not support item assignment Jython
Los textos son inmutables: no se pueden modificar letra por letra. Cada método devuelve un texto nuevo y deja el original intacto.
" Ana.Lopez@Correo.COM ". Límpialo (sin espacios y en minúsculas), extrae el nombre de usuario (lo que va antes de la @) y salúdalo.
Ver una pista
Encadena métodos: .strip().lower(). Luego .split("@") te da una lista con dos partes; la primera es [0].
Ver solución
email = " Ana.Lopez@Correo.COM "
limpio = email.strip().lower()
usuario = limpio.split("@")[0]
print(limpio)
print(usuario)
print(f"Bienvenida, {usuario.replace('.', ' ').title()}")ana.lopez@correo.com ana.lopez Bienvenida, Ana Lopez
¿Qué da "Python"[1:3]?
Entrada y salida
Objetivo: pedirle datos al usuario y mostrar resultados bien presentados.
input() muestra una pregunta, espera a que el usuario escriba algo y te lo devuelve.
nombre = input("¿Cómo te llamas? ")
print(f"Hola, {nombre}. ¡Bienvenido a Python!")¿Cómo te llamas? Ana Hola, Ana. ¡Bienvenido a Python!
input() siempre devuelve texto
edad = int(input("¿Cuántos años tienes? "))
print(f"El próximo año tendrás {edad + 1}")¿Cuántos años tienes? 20 El próximo año tendrás 21
Si no conviertes la respuesta, pasa esto:
edad = input("¿Cuántos años tienes? ")
print(edad + 1)¿Cuántos años tienes? 20
Traceback (most recent call last):
File "main.py", line 2, in <module>
print(edad + 1)
~~~~~^~~
TypeError: can only concatenate str (not "int") to strPara Python, "20" es texto y no se puede sumar con el número 1. La solución es la del ejemplo anterior: int(input(...)) o float(input(...)).
Opciones de print()
print("a", "b", "c")
print("a", "b", "c", sep="-") # sep: qué poner entre los valores
print("Sin salto", end=" ") # end: qué poner al final (por defecto, un salto)
print("de línea")a b c a-b-c Sin salto de línea
Ver solución
a = float(input("Primer número: "))
b = float(input("Segundo número: "))
print(f"Suma: {a + b}")
print(f"Promedio: {(a + b) / 2}")Primer número: 8 Segundo número: 5 Suma: 13.0 Promedio: 6.5
El usuario escribe 5 en x = input(). ¿Qué da x * 2?
Condicionales: tomar decisiones
Objetivo: que tu programa haga cosas distintas según la situación.
temperatura = 30
if temperatura > 25:
print("Hace calor")
print("Lleva agua")
print("Esto se imprime siempre")Hace calor Lleva agua Esto se imprime siempre
if van con 4 espacios al inicio, después de los dos puntos :. Así sabe Python qué está “dentro” de la condición. Si olvidas los espacios o los dos puntos, verás un IndentationError o un SyntaxError.if / else
edad = 15
if edad >= 18:
print("Puedes votar")
else:
print(f"Te faltan {18 - edad} años para votar")Te faltan 3 años para votar
Varias opciones con elif
Python revisa las condiciones de arriba hacia abajo y ejecuta solo la primera que se cumple.
nota = 7.5
if nota >= 9:
print("Excelente")
elif nota >= 7:
print("Bien")
elif nota >= 6:
print("Aprobado")
else:
print("Reprobado")Bien
Prueba con Editar: cambia la nota a 9.5, a 6 y a 3, y ejecuta cada vez.
Atajos útiles
edad = 20
estado = "mayor de edad" if edad >= 18 else "menor de edad"
print(estado)
carrito = []
if not carrito: # una lista vacía cuenta como False
print("El carrito está vacío")mayor de edad El carrito está vacío
match: elegir entre muchos casos
dia = "sábado"
match dia:
case "sábado" | "domingo":
print("Fin de semana")
case "lunes":
print("Inicio de semana")
case _: # _ significa "cualquier otro caso"
print("Día laborable")Fin de semana
Ver una pista
“Divisible entre 4” es año % 4 == 0. Combina las condiciones con and, or y paréntesis.
Ver solución
año = 2024
if (año % 4 == 0 and año % 100 != 0) or año % 400 == 0:
print(f"{año} es bisiesto")
else:
print(f"{año} no es bisiesto")2024 es bisiesto
1900 no es bisiesto y 2000 sí lo es.
En el ejemplo de elif, si nota = 9.5, ¿qué se imprime?
Bucles: repetir sin copiar y pegar
Objetivo: repetir instrucciones con for y while.
for: recorrer una colección
frutas = ["manzana", "pera", "uva"]
for fruta in frutas:
print(f"Me gusta la {fruta}")Me gusta la manzana Me gusta la pera Me gusta la uva
range(): contar
for i in range(5): # 0, 1, 2, 3, 4
print(i, end=" ")
print()
print(list(range(2, 11, 2))) # de 2 a 10, de 2 en 20 1 2 3 4 [2, 4, 6, 8, 10]
range(5) da 0, 1, 2, 3 y 4: cinco números, empezando en 0 y sin incluir el 5.
Acumular resultados
total = 0
for n in range(1, 101):
total += n
print(f"La suma de 1 a 100 es {total}")
for i in range(1, 6):
print(f"7 x {i} = {7 * i}")La suma de 1 a 100 es 5050 7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35
while: repetir mientras algo se cumpla
cuenta = 5
while cuenta > 0:
print(cuenta)
cuenta -= 1
print("¡Despegue!")5 4 3 2 1 ¡Despegue!
while nunca se vuelve falsa, el bucle no termina nunca. Aquí, cuenta -= 1 evita eso. Si te pasa en esta página, no te preocupes: el programa se detiene solo después de 10 segundos.break y continue
for n in range(1, 11):
if n % 2 == 0:
continue # salta al siguiente número
if n > 7:
break # termina el bucle
print(n)1 3 5 7
Un juego: adivina el número
secreto = 37
intentos = 0
while True:
intento = int(input("Adivina el número (1-100): "))
intentos += 1
if intento < secreto:
print("Más alto")
elif intento > secreto:
print("Más bajo")
else:
print(f"¡Correcto! Lo lograste en {intentos} intentos")
breakAdivina el número (1-100): 50 Más bajo Adivina el número (1-100): 25 Más alto Adivina el número (1-100): 37 ¡Correcto! Lo lograste en 3 intentos
Cambia las Entradas para probar otros intentos. while True repite para siempre hasta que un break lo detiene.
Bucles dentro de bucles
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end="\t")
print()1 2 3 2 4 6 3 6 9
Ver una pista
Revisa primero el caso de “ambos” (n % 15 == 0). Si lo revisas al final, nunca llegará a ejecutarse.
Ver solución
for n in range(1, 16):
if n % 15 == 0:
print("FizzBuzz")
elif n % 3 == 0:
print("Fizz")
elif n % 5 == 0:
print("Buzz")
else:
print(n)1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
¿Cuántas veces se repite for i in range(1, 4):?
Listas
Objetivo: guardar muchos valores en orden y trabajar con ellos.
numeros = [10, 20, 30, 40, 50]
print(numeros[0], numeros[-1])
print(numeros[1:3])
print(len(numeros), sum(numeros), min(numeros), max(numeros))10 50 [20, 30] 5 150 10 50
Modificar una lista
compras = ["pan", "leche"]
compras.append("huevos") # agrega al final
compras.insert(0, "café") # agrega en una posición
compras.remove("leche") # quita por valor
ultimo = compras.pop() # quita y devuelve el último
compras[0] = "té" # reemplaza
print(compras)
print(ultimo)
print("pan" in compras)['té', 'pan'] huevos True
Ordenar y buscar
nums = [5, 2, 8, 1, 9]
print(sorted(nums)) # devuelve una lista nueva ordenada
print(nums) # la original no cambió
nums.sort(reverse=True) # ordena la lista misma, de mayor a menor
print(nums)
print(nums.index(8), nums.count(5))[1, 2, 5, 8, 9] [5, 2, 8, 1, 9] [9, 8, 5, 2, 1] 1 1
sorted(lista) devuelve una lista nueva; lista.sort() cambia la lista original y no devuelve nada.
La trampa de la copia
a = [1, 2, 3]
b = a # b NO es una copia: es otro nombre para la misma lista
b.append(4)
print(a)
c = a.copy() # copia de verdad
c.append(99)
print(a, c)[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 99]
b = a no fotocopia la lista: le pone una segunda etiqueta a la misma caja. Lo que hagas con b le pasa a a. Para tener otra caja, usa .copy().Comprensiones de lista
Una forma corta de crear una lista a partir de otra. Se lee: “dame esto por cada elemento, si cumple esta condición”.
cuadrados = [x ** 2 for x in range(1, 6)]
pares = [x for x in range(10) if x % 2 == 0]
nombres = ["ana", "luis", "marta"]
print(cuadrados)
print(pares)
print([n.capitalize() for n in nombres])[1, 4, 9, 16, 25] [0, 2, 4, 6, 8] ['Ana', 'Luis', 'Marta']
Listas de listas
matriz = [[1, 2, 3],
[4, 5, 6]]
print(matriz[1]) # segunda fila
print(matriz[1][2]) # fila 1, columna 2[4, 5, 6] 6
[22.5, 27.1, 19.8, 30.2, 25.0, 28.4, 21.3], calcula el promedio (con 1 decimal) y la máxima, y haz una lista con las mayores de 25°.
Ver solución
temperaturas = [22.5, 27.1, 19.8, 30.2, 25.0, 28.4, 21.3]
promedio = sum(temperaturas) / len(temperaturas)
calurosos = [t for t in temperaturas if t > 25]
print(f"Promedio: {promedio:.1f}")
print(f"Máxima: {max(temperaturas)}")
print(f"Días de más de 25°: {calurosos}")Promedio: 24.9 Máxima: 30.2 Días de más de 25°: [27.1, 30.2, 28.4]
Si x = [1, 2] y ejecutas x.append(3), ¿cuánto vale x?
Tuplas y conjuntos
Objetivo: conocer dos colecciones más y saber cuándo conviene cada una.
Tuplas: listas que no cambian
punto = (3, 4)
x, y = punto # desempaquetar
print(x, y)
try:
punto[0] = 10
except TypeError as error:
print("Error:", error)
a, b = 1, 2
a, b = b, a # intercambiar valores en una línea
print(a, b)3 4 Error: 'tuple' object does not support item assignment 2 1
Usa tuplas para datos que van juntos y no deben modificarse, como unas coordenadas o una fecha.
Conjuntos (sets): sin repetidos
numeros = [1, 2, 2, 3, 3, 3, 4]
print(set(numeros)) # elimina los repetidos
print(len(set(numeros)))
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
print(A | B) # unión: en A o en B
print(A & B) # intersección: en ambos
print(A - B) # diferencia: en A pero no en B{1, 2, 3, 4}
4
{1, 2, 3, 4, 5, 6}
{3, 4}
{1, 2}sorted() si necesitas verlos ordenados.| Colección | Se escribe | ¿Ordenada? | ¿Modificable? | ¿Repetidos? |
|---|---|---|---|---|
| Lista | [1, 2] | Sí | Sí | Sí |
| Tupla | (1, 2) | Sí | No | Sí |
| Conjunto | {1, 2} | No | Sí | No |
| Diccionario | {"a": 1} | Sí (por orden de inserción) | Sí | Claves no |
Ver solución
python = ["Ana", "Luis", "Marta", "Pedro"]
excel = ["Luis", "Sofía", "Pedro", "Diego"]
print(sorted(set(python) & set(excel))) # en ambos cursos
print(sorted(set(python) - set(excel))) # solo en Python['Luis', 'Pedro'] ['Ana', 'Marta']
¿Qué da len({1, 1, 2})?
Diccionarios
Objetivo: guardar información en pares clave → valor, como una ficha.
persona = {"nombre": "Ana", "edad": 20, "ciudad": "Lima"}
print(persona["nombre"])
persona["edad"] = 21 # modificar
persona["email"] = "ana@mail.com" # agregar
del persona["ciudad"] # eliminar
print(persona)
print(len(persona), "email" in persona)Ana
{'nombre': 'Ana', 'edad': 21, 'email': 'ana@mail.com'}
3 TrueLeer sin errores con get()
print(persona.get("telefono", "no registrado")) # con valor por defecto
try:
print(persona["telefono"])
except KeyError as error:
print("No existe la clave", error)no registrado No existe la clave 'telefono'
Recorrer un diccionario
for clave, valor in persona.items():
print(f"{clave}: {valor}")
print(list(persona.keys()))
print(list(persona.values()))nombre: Ana edad: 21 email: ana@mail.com ['nombre', 'edad', 'email'] ['Ana', 21, 'ana@mail.com']
Patrón clásico: contar
texto = "el perro y el gato y el loro"
conteo = {}
for palabra in texto.split():
conteo[palabra] = conteo.get(palabra, 0) + 1
print(conteo){'el': 3, 'perro': 1, 'y': 2, 'gato': 1, 'loro': 1}Listas de diccionarios: como una tabla
estudiantes = [
{"nombre": "Ana", "nota": 8.5},
{"nombre": "Luis", "nota": 6.0},
{"nombre": "Marta", "nota": 9.2},
]
for e in estudiantes:
estado = "aprobado" if e["nota"] >= 7 else "debe mejorar"
print(f"{e['nombre']:<6} {e['nota']:>4} {estado}")Ana 8.5 aprobado Luis 6.0 debe mejorar Marta 9.2 aprobado
En una f-string, :<6 alinea a la izquierda en 6 espacios y :>4 alinea a la derecha en 4.
Ver solución
inventario = {"lápiz": 12, "cuaderno": 3, "borrador": 8, "regla": 2}
inventario["lápiz"] -= 5 # se vendieron 5 lápices
for producto, stock in inventario.items():
if stock < 5:
print(f"Reponer {producto}: quedan {stock}")Reponer cuaderno: quedan 3 Reponer regla: quedan 2
Si d = {"a": 1}, ¿qué da d.get("b", 0)?
Funciones
Objetivo: crear tus propias órdenes reutilizables.
Una función es un bloque de código con nombre. Lo escribes una vez y lo usas cuantas veces quieras. Se crea con def.
def saludar():
print("¡Hola!")
print("Bienvenido")
saludar() # llamar a la función
saludar()¡Hola! Bienvenido ¡Hola! Bienvenido
Parámetros y return
Los parámetros son los datos que la función recibe; return es el resultado que devuelve.
def area_rectangulo(base, altura):
return base * altura
a = area_rectangulo(5, 3)
print(a)
print(area_rectangulo(2, 10) + 1)15 21
return).Valores por defecto y argumentos con nombre
def saludar(nombre, saludo="Hola"):
return f"¡{saludo}, {nombre}!"
print(saludar("Ana"))
print(saludar("Luis", "Buenos días"))
print(saludar(saludo="Qué tal", nombre="Marta")) # argumentos con nombre¡Hola, Ana! ¡Buenos días, Luis! ¡Qué tal, Marta!
Devolver varios valores
def resumen(numeros):
"""Devuelve el mínimo, el máximo y el promedio de una lista."""
return min(numeros), max(numeros), sum(numeros) / len(numeros)
menor, mayor, promedio = resumen([4, 8, 15, 16, 23, 42])
print(menor, mayor, promedio)
print(resumen.__doc__)4 42 18.0 Devuelve el mínimo, el máximo y el promedio de una lista.
El texto entre triples comillas al inicio es la docstring: documenta qué hace la función.
Lo de adentro se queda adentro
x = 10
def cambiar():
x = 5 # esta x es local: solo existe dentro de la función
print("dentro:", x)
cambiar()
print("fuera:", x)dentro: 5 fuera: 10
print no es lo mismo que return
def con_print(n):
print(n * 2)
def con_return(n):
return n * 2
resultado1 = con_print(5)
resultado2 = con_return(5)
print(resultado1, resultado2)10 None 10
con_print muestra el 10 en pantalla, pero no devuelve nada (None). Si necesitas usar el resultado después, usa return.
es_primo(n), que devuelva True si n es primo (solo se divide entre 1 y sí mismo). Úsala para listar los primos del 1 al 30.
Ver una pista
Prueba dividir n entre cada número desde 2. Si alguna división da resto 0, no es primo. Basta con probar hasta la raíz cuadrada de n.
Ver solución
def es_primo(n):
if n < 2:
return False
for divisor in range(2, int(n ** 0.5) + 1):
if n % divisor == 0:
return False
return True
print(es_primo(7), es_primo(10))
print([n for n in range(1, 31) if es_primo(n)])True False [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
¿Qué devuelve una función que no tiene return?
Errores y excepciones
Objetivo: que tu programa no se caiga cuando algo sale mal.
| Error | Cuándo aparece |
|---|---|
SyntaxError | Escribiste algo que Python no entiende: falta un paréntesis, unas comillas o los dos puntos |
NameError | Usas una variable que no existe (a menudo, un error de escritura) |
TypeError | Mezclas tipos que no combinan, como texto + número |
ValueError | El tipo es correcto, pero el valor no sirve: int("abc") |
IndexError / KeyError | Pides una posición de lista o una clave de diccionario que no existe |
ZeroDivisionError | Divides entre cero |
try / except: intentar y atrapar
texto = "abc"
try:
numero = int(texto)
print("Número:", numero)
except ValueError:
print(f"'{texto}' no es un número")'abc' no es un número
def dividir(a, b):
try:
resultado = a / b
except ZeroDivisionError:
return "No se puede dividir entre cero"
except TypeError:
return "Solo se pueden dividir números"
else:
return resultado # solo si no hubo error
finally:
print("(división intentada)") # se ejecuta siempre
print(dividir(10, 4))
print(dividir(10, 0))
print(dividir(10, "dos"))(división intentada) 2.5 (división intentada) No se puede dividir entre cero (división intentada) Solo se pueden dividir números
Validar lo que escribe el usuario
while True:
try:
edad = int(input("Tu edad: "))
break
except ValueError:
print("Escribe un número entero, por ejemplo 20")
print(f"Edad registrada: {edad}")Tu edad: veinte Escribe un número entero, por ejemplo 20 Tu edad: 20 Edad registrada: 20
Lanzar tus propios errores con raise
def retirar(saldo, monto):
if monto <= 0:
raise ValueError("El monto debe ser positivo")
if monto > saldo:
raise ValueError(f"Saldo insuficiente: tienes {saldo}")
return saldo - monto
print(retirar(100, 30))
try:
retirar(100, 500)
except ValueError as error:
print("No se pudo retirar:", error)70 No se pudo retirar: Saldo insuficiente: tienes 100
except: sin tipo atrapa cualquier error, incluso los que no esperabas, y los esconde. Indica siempre qué error esperas: except ValueError:.["10", "x", "5", "3.5", ""]. Suma los valores que sean números válidos y guarda en otra lista los que no lo sean.
Ver solución
datos = ["10", "x", "5", "3.5", ""]
total = 0
invalidos = []
for d in datos:
try:
total += float(d)
except ValueError:
invalidos.append(d)
print(f"Total: {total}")
print(f"Inválidos: {invalidos}")Total: 18.5 Inválidos: ['x', '']
¿Cuándo se ejecuta el bloque finally?
Archivos
Objetivo: guardar y leer información para que no se pierda al cerrar el programa.
Ejecuta estos ejemplos en orden: cada uno usa el archivo que creó el anterior.
Escribir
with open("notas.txt", "w", encoding="utf-8") as archivo:
archivo.write("Ana,8.5\n")
archivo.write("Luis,6.0\n")
archivo.write("Marta,9.2\n")
print("Archivo guardado")Archivo guardado
with abre el archivo y lo cierra solo al terminar. "w" significa escribir (borra lo que había), y \n es un salto de línea. Usa siempre encoding="utf-8" para que las tildes y la ñ se guarden bien.
Leer
with open("notas.txt", encoding="utf-8") as archivo:
contenido = archivo.read()
print(contenido)Ana,8.5 Luis,6.0 Marta,9.2
with open("notas.txt", encoding="utf-8") as archivo:
for linea in archivo:
nombre, nota = linea.strip().split(",")
print(f"{nombre} sacó {float(nota)}")Ana sacó 8.5 Luis sacó 6.0 Marta sacó 9.2
Agregar al final
with open("notas.txt", "a", encoding="utf-8") as archivo: # "a" = agregar al final
archivo.write("Pedro,7.0\n")
with open("notas.txt", encoding="utf-8") as archivo:
print(len(archivo.readlines()), "líneas")4 líneas
JSON: guardar listas y diccionarios
import json
config = {"usuario": "ana", "tema": "oscuro", "favoritos": [3, 7, 12]}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config, f, ensure_ascii=False, indent=2)
with open("config.json", encoding="utf-8") as f:
cargado = json.load(f)
print(cargado["favoritos"])
print(cargado == config)[3, 7, 12] True
CSV: datos en columnas
import csv
with open("notas.txt", encoding="utf-8") as f:
lector = csv.reader(f)
filas = [(nombre, float(nota)) for nombre, nota in lector]
mejor = max(filas, key=lambda fila: fila[1])
print(filas)
print("Mejor nota:", mejor)[('Ana', 8.5), ('Luis', 6.0), ('Marta', 9.2), ('Pedro', 7.0)]
Mejor nota: ('Marta', 9.2)Cuando el archivo no existe
try:
with open("no_existe.txt", encoding="utf-8") as f:
print(f.read())
except FileNotFoundError:
print("El archivo no existe. Revisa el nombre y la carpeta.")El archivo no existe. Revisa el nombre y la carpeta.
notas.txt y calcula cuántos estudiantes hay y su promedio, con 2 decimales.
Ver solución
with open("notas.txt", encoding="utf-8") as f:
notas = [float(linea.strip().split(",")[1]) for linea in f]
print(f"{len(notas)} estudiantes, promedio {sum(notas) / len(notas):.2f}")4 estudiantes, promedio 7.67
Quieres añadir una línea a un archivo sin borrar lo que ya tiene. ¿Qué modo usas?
Módulos y librerías
Objetivo: usar código que ya escribieron otros y organizar el tuyo en archivos.
Python viene con una “biblioteca estándar” enorme. Para usar una parte, la importas con import.
import math
print(math.sqrt(16))
print(math.pi)
print(math.floor(3.7), math.ceil(3.2)) # redondear hacia abajo / arriba4.0 3.141592653589793 3 4
from math import sqrt, pi # importar solo lo que necesitas
print(sqrt(25), round(pi, 2))
import datetime as dt # importar con un nombre corto
print(dt.date(2026, 10, 7))5.0 3.14 2026-10-07
Números al azar
import random
random.seed(42) # fija la "semilla": así obtienes siempre los mismos resultados
print(random.randint(1, 6))
print(random.choice(["piedra", "papel", "tijera"]))
cartas = [1, 2, 3, 4, 5]
random.shuffle(cartas)
print(cartas)6 piedra [2, 4, 5, 3, 1]
Sin random.seed() obtendrías resultados distintos cada vez. La semilla sirve para que un experimento se pueda repetir.
Fechas
from datetime import date, timedelta
hoy = date(2026, 10, 7)
print(hoy + timedelta(days=30))
print(hoy.strftime("%d/%m/%Y"))
print((date(2026, 12, 25) - hoy).days, "días para Navidad")2026-11-06 07/10/2026 79 días para Navidad
Tus propios módulos
Cualquier archivo .py es un módulo. Si tienes estos dos archivos en la misma carpeta:
# archivo: utilidades.py
def celsius_a_fahrenheit(c):
return c * 9 / 5 + 32# archivo: main.py (en la misma carpeta)
import utilidades
print(utilidades.celsius_a_fahrenheit(25))77.0
Librerías externas con pip
Hay cientos de miles de librerías gratuitas en pypi.org. Se instalan desde la terminal (en Colab, con !pip install ...):
pip install requestsAlgunas muy populares: requests (internet), pandas (datos en tablas), matplotlib (gráficos), flask (páginas web) y pygame (videojuegos).
# por cada 10 veces.
Ver una pista
Usa un diccionario para contar (como en la lección 9) y random.randint(1, 6) dentro de un for. "#" * 5 da #####.
Ver solución
import random
random.seed(1)
conteo = {}
for _ in range(600):
cara = random.randint(1, 6)
conteo[cara] = conteo.get(cara, 0) + 1
for cara in sorted(conteo):
print(cara, "#" * (conteo[cara] // 10), conteo[cara])1 ########## 104 2 ########## 102 3 ########## 103 4 ######### 94 5 ########### 113 6 ######## 84
Cada cara debería salir unas 100 veces. Con más lanzamientos, los números se parecen cada vez más.
Después de from math import sqrt, ¿cómo calculas la raíz de 9?
Clases y objetos
Objetivo: crear tus propios tipos de datos que junten información y comportamiento.
class Perro:
def __init__(self, nombre, edad): # se ejecuta al crear el objeto
self.nombre = nombre # atributos: datos del objeto
self.edad = edad
def ladrar(self): # método: algo que el objeto sabe hacer
return f"{self.nombre} dice: ¡Guau!"
firulais = Perro("Firulais", 3)
toby = Perro("Toby", 5)
print(firulais.ladrar())
print(toby.nombre, toby.edad)Firulais dice: ¡Guau! Toby 5
__init__se ejecuta automáticamente al crear el objeto y prepara sus datos.selfes “este objeto en particular”. Por esoself.nombrees el nombre de cada perro.- Los atributos son los datos (nombre, edad) y los métodos son las funciones de la clase (ladrar).
Un ejemplo completo: una cuenta bancaria
class CuentaBancaria:
def __init__(self, titular, saldo=0):
self.titular = titular
self.saldo = saldo
def depositar(self, monto):
if monto <= 0:
raise ValueError("El depósito debe ser positivo")
self.saldo += monto
def retirar(self, monto):
if monto > self.saldo:
raise ValueError("Saldo insuficiente")
self.saldo -= monto
def __str__(self): # cómo se ve al imprimirlo
return f"Cuenta de {self.titular}: ${self.saldo:,.2f}"
cuenta = CuentaBancaria("Ana", 100)
cuenta.depositar(50)
cuenta.retirar(30)
print(cuenta)
try:
cuenta.retirar(1000)
except ValueError as error:
print("Error:", error)Cuenta de Ana: $120.00 Error: Saldo insuficiente
La clase protege sus reglas: no se puede retirar más de lo que hay. __str__ define cómo se ve el objeto al imprimirlo.
Herencia
Una clase puede heredar de otra: recibe todo lo que la otra tiene y cambia solo lo necesario.
class Animal:
def __init__(self, nombre):
self.nombre = nombre
def hablar(self):
return "..."
def presentarse(self):
return f"Soy {self.nombre} y digo {self.hablar()}"
class Gato(Animal): # Gato hereda todo de Animal
def hablar(self): # y redefine este método
return "miau"
class Vaca(Animal):
def hablar(self):
return "muu"
for animal in [Gato("Michi"), Vaca("Lola"), Animal("Algo")]:
print(animal.presentarse())Soy Michi y digo miau Soy Lola y digo muu Soy Algo y digo ...
Rectangulo con base y altura, y los métodos area(), perimetro() y es_cuadrado().
Ver solución
class Rectangulo:
def __init__(self, base, altura):
self.base = base
self.altura = altura
def area(self):
return self.base * self.altura
def perimetro(self):
return 2 * (self.base + self.altura)
def es_cuadrado(self):
return self.base == self.altura
r = Rectangulo(4, 6)
c = Rectangulo(5, 5)
print(r.area(), r.perimetro(), r.es_cuadrado())
print(c.area(), c.perimetro(), c.es_cuadrado())24 20 False 25 20 True
¿Cuándo se ejecuta __init__?
Herramientas pythónicas
Objetivo: escribir código más corto y claro, como lo escribe la gente con experiencia en Python.
enumerate y zip
frutas = ["manzana", "pera", "uva"]
for i, fruta in enumerate(frutas, start=1):
print(i, fruta)
nombres = ["Ana", "Luis", "Marta"]
notas = [8.5, 6.0, 9.2]
for nombre, nota in zip(nombres, notas):
print(f"{nombre}: {nota}")1 manzana 2 pera 3 uva Ana: 8.5 Luis: 6.0 Marta: 9.2
Comprensiones de diccionario y de conjunto
precios = {"pan": 1.2, "leche": 0.9, "queso": 4.5}
con_iva = {producto: round(p * 1.18, 2) for producto, p in precios.items()}
print(con_iva)
print({len(p) for p in ["sol", "luna", "mar", "cielo"]}) # comprensión de conjunto{'pan': 1.42, 'leche': 1.06, 'queso': 5.31}
{3, 4, 5}lambda, sorted, map y filter
lambda crea una función pequeña de una sola línea, sin nombre. Es muy útil para decirle a sorted o a max según qué deben ordenar.
personas = [("Ana", 25), ("Luis", 19), ("Marta", 32)]
print(sorted(personas, key=lambda p: p[1])) # ordenar por edad
print(max(personas, key=lambda p: p[1]))
print(list(map(lambda p: p[0].upper(), personas)))
print(list(filter(lambda p: p[1] >= 21, personas)))[('Luis', 19), ('Ana', 25), ('Marta', 32)]
('Marta', 32)
['ANA', 'LUIS', 'MARTA']
[('Ana', 25), ('Marta', 32)]any y all
notas = [7.5, 8.2, 6.1, 9.0]
print(all(n >= 6 for n in notas)) # ¿todos aprobaron?
print(any(n >= 9 for n in notas)) # ¿alguien sacó 9 o más?True True
*args y **kwargs
def promedio(*numeros): # *: acepta cualquier cantidad de argumentos
return sum(numeros) / len(numeros)
def ficha(**datos): # **: acepta argumentos con nombre libres
for clave, valor in datos.items():
print(f"{clave} = {valor}")
print(promedio(4, 8, 6))
print(promedio(10, 20))
ficha(nombre="Ana", ciudad="Lima", edad=20)6.0 15.0 nombre = Ana ciudad = Lima edad = 20
["python", "es", "un", "lenguaje", "muy", "versátil"], obtén las palabras de más de 3 letras ordenadas de más larga a más corta, y un diccionario con la longitud de cada palabra.
Ver solución
palabras = ["python", "es", "un", "lenguaje", "muy", "versátil"]
largas = sorted([p for p in palabras if len(p) > 3], key=len, reverse=True)
longitudes = {p: len(p) for p in palabras}
print(largas)
print(longitudes)['lenguaje', 'versátil', 'python']
{'python': 6, 'es': 2, 'un': 2, 'lenguaje': 8, 'muy': 3, 'versátil': 8}¿Qué da list(zip([1, 2], ["a", "b"]))?
Iteradores, generadores y decoradores
Objetivo: entender cómo funciona for por dentro y conocer dos herramientas avanzadas muy usadas.
Iteradores
Cuando haces un for, Python pide los elementos uno por uno con next(). Puedes hacerlo a mano:
colores = ["rojo", "verde", "azul"]
it = iter(colores)
print(next(it))
print(next(it))
print(next(it))rojo verde azul
Generadores: valores bajo demanda
Una función con yield no devuelve todo de golpe: entrega un valor, se pausa y continúa cuando le piden el siguiente.
def cuenta_regresiva(n):
while n > 0:
yield n # entrega un valor y se pausa hasta que pidan el siguiente
n -= 1
for x in cuenta_regresiva(3):
print(x)
print(list(cuenta_regresiva(5)))3 2 1 [5, 4, 3, 2, 1]
def fibonacci():
a, b = 0, 1
while True: # infinito, pero solo calcula lo que se pide
yield a
a, b = b, a + b
fib = fibonacci()
print([next(fib) for _ in range(10)])
# expresión generadora: como una comprensión, pero sin guardar la lista en memoria
print(sum(x ** 2 for x in range(1_000_000)))[0, 1, 1, 2, 3, 5, 8, 13, 21, 34] 333332833333500000
Decoradores: envolver funciones
Un decorador recibe una función y devuelve otra que le agrega algo, sin tocar el código original. Se aplica con @.
def anunciar(funcion):
def envoltura(*args):
print(f"Llamando a {funcion.__name__}{args}")
resultado = funcion(*args)
print(f"Resultado: {resultado}")
return resultado
return envoltura
@anunciar # equivale a: sumar = anunciar(sumar)
def sumar(a, b):
return a + b
sumar(3, 4)Llamando a sumar(3, 4) Resultado: 7
Los verás mucho en librerías web como Flask (@app.route("/")) y en pruebas automáticas.
pares(limite), que entregue los números pares desde 0 hasta limite. Muestra los pares hasta 10 y suma los pares hasta 100.
Ver solución
def pares(limite):
n = 0
while n <= limite:
yield n
n += 2
print(list(pares(10)))
print(sum(pares(100)))[0, 2, 4, 6, 8, 10] 2550
¿Qué palabra convierte una función en generador?
Buenas prácticas
Objetivo: escribir código que otras personas (y tú en seis meses) puedan entender y mantener.
Estilo PEP 8
- Variables y funciones en minúsculas con guion bajo:
precio_total,calcular_iva(). - Clases con mayúscula inicial:
CuentaBancaria. - Sangría de 4 espacios y líneas de menos de 80 caracteres, más o menos.
- Nombres que expliquen qué guardan:
edad_clienteen lugar dex.
Anotaciones de tipo
Indican qué tipos espera y devuelve una función. Python no las obliga, pero tu editor las usa para avisarte de errores.
def promedio(numeros: list[float]) -> float:
"""Calcula el promedio de una lista de números."""
if not numeros:
raise ValueError("La lista está vacía")
return sum(numeros) / len(numeros)
print(promedio([7.5, 8.0, 9.5]))8.333333333333334
Depurar con f-strings
x = 5
lista = [1, 2, 3]
print(f"{x=}") # muestra el nombre y el valor: útil para depurar
print(f"{len(lista)=}")x=5 len(lista)=3
Probar tu código
def es_palindromo(texto):
limpio = texto.lower().replace(" ", "")
return limpio == limpio[::-1]
# pruebas rápidas: si alguna falla, Python lo avisa con un AssertionError
assert es_palindromo("Anita lava la tina")
assert es_palindromo("oso")
assert not es_palindromo("python")
print("Todas las pruebas pasaron")Todas las pruebas pasaron
Cuando tus proyectos crezcan, usa pytest: guardas funciones de prueba como estas en archivos test_*.py y las ejecutas todas con el comando pytest.
El punto de entrada de un programa
def main():
print("Programa principal")
if __name__ == "__main__": # solo se ejecuta si corres este archivo directamente,
main() # no si otro archivo lo importaPrograma principal
Entornos virtuales
Cada proyecto debería tener su propio entorno, con sus propias librerías, para que no choquen versiones entre proyectos:
python -m venv .venv # crear el entorno (una vez por proyecto)
.venv\Scripts\activate # activarlo en Windows
source .venv/bin/activate # activarlo en Mac o Linux
pip install requests # instalar dentro del entorno
pip freeze > requirements.txt # guardar la lista de libreríasSegún PEP 8, ¿cómo deberías nombrar una clase que representa un carrito de compras?
Proyecto final: gestor de tareas
Objetivo: construir un programa completo que junte todo lo aprendido: clases, listas, errores, archivos y un menú interactivo. Intenta cada paso antes de abrir la solución.
Tarea con un título y un estado (hecha o no). Al imprimirla debe verse como [ ] Estudiar Python o [x] Estudiar Python.
Ver solución
class Tarea:
def __init__(self, titulo, hecha=False):
self.titulo = titulo
self.hecha = hecha
def __str__(self):
marca = "x" if self.hecha else " "
return f"[{marca}] {self.titulo}"
t = Tarea("Estudiar Python")
print(t)
t.hecha = True
print(t)[ ] Estudiar Python [x] Estudiar Python
GestorTareas, que guarde una lista de tareas y tenga los métodos agregar, completar, listar y pendientes. Valida los datos con raise.
Ver solución
class GestorTareas:
def __init__(self):
self.tareas = []
def agregar(self, titulo):
titulo = titulo.strip()
if not titulo:
raise ValueError("El título no puede estar vacío")
self.tareas.append(Tarea(titulo))
def completar(self, numero):
if not 1 <= numero <= len(self.tareas):
raise ValueError(f"No existe la tarea {numero}")
self.tareas[numero - 1].hecha = True
def listar(self):
if not self.tareas:
print("No hay tareas")
for i, tarea in enumerate(self.tareas, start=1):
print(f"{i}. {tarea}")
def pendientes(self):
return sum(1 for t in self.tareas if not t.hecha)
gestor = GestorTareas()
gestor.agregar("Estudiar Python")
gestor.agregar("Hacer ejercicio")
gestor.completar(1)
gestor.listar()
print("Pendientes:", gestor.pendientes())1. [x] Estudiar Python 2. [ ] Hacer ejercicio Pendientes: 1
guardar(gestor) y cargar() usando un archivo JSON. Si el archivo no existe, empieza con la lista vacía.
Ver solución
import json
def guardar(gestor, ruta="tareas.json"):
datos = [{"titulo": t.titulo, "hecha": t.hecha} for t in gestor.tareas]
with open(ruta, "w", encoding="utf-8") as f:
json.dump(datos, f, ensure_ascii=False, indent=2)
def cargar(ruta="tareas.json"):
gestor = GestorTareas()
try:
with open(ruta, encoding="utf-8") as f:
for d in json.load(f):
gestor.tareas.append(Tarea(d["titulo"], d["hecha"]))
except FileNotFoundError:
pass # primera vez: empezamos sin tareas
return gestor
guardar(gestor)
otro = cargar()
otro.listar()1. [x] Estudiar Python 2. [ ] Hacer ejercicio
try/except para que un error no cierre el programa.
Ver solución
def menu():
gestor = cargar()
while True:
print("\n1) Ver 2) Agregar 3) Completar 4) Salir")
opcion = input("Elige una opción: ").strip()
try:
if opcion == "1":
gestor.listar()
elif opcion == "2":
gestor.agregar(input("Título: "))
print("Tarea agregada")
elif opcion == "3":
gestor.completar(int(input("Número de tarea: ")))
print("¡Bien hecho!")
elif opcion == "4":
guardar(gestor)
print(f"Guardado. Tareas pendientes: {gestor.pendientes()}")
break
else:
print("Opción no válida")
except ValueError as error:
print("Error:", error)
menu()1) Ver 2) Agregar 3) Completar 4) Salir Elige una opción: 2 Título: Leer un libro Tarea agregada 1) Ver 2) Agregar 3) Completar 4) Salir Elige una opción: 3 Número de tarea: 7 Error: No existe la tarea 7 1) Ver 2) Agregar 3) Completar 4) Salir Elige una opción: 3 Número de tarea: 2 ¡Bien hecho! 1) Ver 2) Agregar 3) Completar 4) Salir Elige una opción: 1 1. [x] Estudiar Python 2. [x] Hacer ejercicio 3. [ ] Leer un libro 1) Ver 2) Agregar 3) Completar 4) Salir Elige una opción: 4 Guardado. Tareas pendientes: 1
Cambia las Entradas para probar otros caminos. Fíjate en que el número 7 no cerró el programa: mostró un error amable y siguió funcionando.
datetime o una prioridad (alta, media, baja), y muestra las tareas ordenadas con sorted(..., key=...).
Consola libre
Escribe cualquier programa y ejecútalo. Comparte la memoria con los ejemplos de la guía, así que puedes usar las variables y funciones que ya creaste.
# Escribe aquí tu código
nombre = input("¿Qué quieres aprender? ")
for i in range(3):
print(f"¡Voy a aprender {nombre}!")Chuleta
Lo esencial de la guía en una tabla, para consultarla mientras programas.
| Para… | Código | Lección |
|---|---|---|
| Mostrar algo | print("hola", x) | 0 |
| Crear una variable | edad = 20 | 1 |
| Convertir tipos | int(), float(), str() | 1 |
| División entera y resto | 7 // 2, 7 % 2 | 2 |
| Insertar variables en texto | f"Hola {nombre}", f"{x:.2f}" | 3 |
| Pedir un dato | int(input("Edad: ")) | 4 |
| Decidir | if ...: elif ...: else: | 5 |
| Repetir | for x in lista:, for i in range(n):, while cond: | 6 |
| Listas | .append(), .remove(), sorted(), len() | 7 |
| Comprensión de lista | [x * 2 for x in lista if x > 0] | 7 |
| Quitar repetidos | set(lista) | 8 |
| Diccionarios | d["clave"], d.get("clave", 0), d.items() | 9 |
| Crear una función | def nombre(param): return ... | 10 |
| Manejar errores | try: ... except ValueError: ... | 11 |
| Leer un archivo | with open("a.txt", encoding="utf-8") as f: | 12 |
| Importar | import math, from random import randint | 13 |
| Crear una clase | class Nombre: def __init__(self, ...): | 14 |
| Numerar y emparejar | enumerate(lista), zip(a, b) | 15 |
| Generador | def gen(): yield valor | 16 |
Para seguir aprendiendo
- Tutorial oficial de Python en español: completo y gratuito.
- Codewars y Exercism: ejercicios cortos con niveles de dificultad.
- Elige un proyecto que te importe: automatizar renombrar archivos, un bot para tu grupo, un juego con pygame o una página con Flask. Se aprende más construyendo que leyendo.
Los resultados de cada ejemplo se obtuvieron ejecutándolos con Python 3.14. El botón ▶ Ejecutar usa Pyodide, Python 3.14 dentro del navegador.