Listas: el trabajo diario
Una lista (list) es una colección ordenada y modificable
de elementos. Se crea con corchetes [] y puede contener cualquier tipo (incluso otros tipos
mezclados, aunque lo normal es que sea homogénea).
frutas = ["manzana", "pera", "uva"]
numeros = [1, 2, 3, 4, 5]
mixta = ["Ana", 25, True]
vacia = []
print(len(frutas)) # 3 — número de elementos
print(frutas[0]) # manzana — el primero
print(frutas[-1]) # uva — el último
1.1 · Añadir y quitar
frutas = []
frutas.append("kivi") # añade al final
frutas.append("mango")
frutas.insert(0, "sandía") # inserta en la posición 0
frutas.remove("kivi") # borra la primera aparición
frutas.pop() # saca y devuelve el último
frutas.pop(0) # saca y devuelve el 0
print(frutas)
append(), remove(),
pop() la modifican en el sitio (no devuelven una copia nueva). Si haces
b = a, ambas variables apuntan a la misma lista: lo que cambies en una se ve
en la otra. Para copiar de verdad usa b = a.copy() o b = list(a).1.2 · Recorrer listas
precios = [9.99, 19.99, 5.50]
for p in precios:
print(f"Precio: {p:.2f} €")
# ¿Necesitas también la posición? → enumerate
for indice, p in enumerate(precios):
print(indice, p)
enumerate() devuelve pares (índice, valor). Es la forma Python de
hacer el clásico «for con contador» sin gestionar tú el contador.Índices y slicing
Toda colección ordenada (strings, listas, tuplas) se indexa desde 0. Los índices
negativos cuentan desde el final: -1 es el último, -2 el penúltimo…
palabra = "Python"
print(palabra[0]) # P
print(palabra[2]) # t
print(palabra[-1]) # n
numeros = [10, 20, 30, 40, 50]
print(numeros[1]) # 20
print(numeros[-2]) # 40
2.1 · Slicing: cortar rebanadas
La sintaxis secuencia[inicio:fin:paso] extrae una rebanada. El fin no se
incluye:
n = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(n[2:5]) # [2, 3, 4] → del índice 2 al 4
print(n[:4]) # [0, 1, 2, 3] → desde el inicio
print(n[6:]) # [6, 7, 8, 9] → hasta el final
print(n[::2]) # [0, 2, 4, 6, 8] → de dos en dos
print(n[::-1]) # [9, 8, ..., 0] → la lista invertida
texto[::-1] invierte un string. Es el truco más corto para el
clásico «¿es esta palabra un palíndromo?».n[15]) Python lanza
IndexError. El slicing, en cambio, nunca da error: devuelve lo que exista
(incluso [] vacío). Comprueba siempre len() antes de acceder a un índice manual.Métodos y ordenación
Las listas vienen con métodos muy útiles. Los que cambian la lista (como
sort, reverse o append) devuelven None; los que
analizan (como count, index) devuelven un valor.
3.1 · Búsquedas y comprobaciones
cola = ["a", "b", "c", "a"]
print("a" in cola) # True — pertenencia
print(cola.count("a")) # 2 — cuántas veces aparece
print(cola.index("b")) # 1 — primera posición
3.2 · Ordenar y su función clave
nombres = ["ana", "carlos", "bea"]
nombres.sort() # ordena la lista EN EL SITIO (None)
print(nombres) # ['ana', 'bea', 'carlos']
nums = [3, 1, 2]
nums.sort(reverse=True) # de mayor a menor
# sorted() devuelve una copia ordenada (no modifica la original)
original = [4, 2]
ordenada = sorted(original) # [2, 4] ; original sigue [4, 2]
sorted(lista, key=funcion) ordena usando una función que extrae la clave.
Por ejemplo, ordenar por la segunda letra: sorted(palabras, key=lambda p: p[1]). En el bloque 3
verás lambda a fondo.3.3 · min, max y sum
notas = [7, 5, 9, 6]
print(min(notas)) # 5
print(max(notas)) # 9
print(sum(notas)) # 27
print(sum(notas) / len(notas)) # 6.75 → la media
3.4 · Unir listas y strings
frase = "Python es genial"
palabras = frase.split() # ['Python', 'es', 'genial']
lista = ["a", "b", "c"]
unido = "-".join(lista) # 'a-b-c'
# unir + listas con extensión
a = [1, 2]
a.extend([3, 4]) # [1, 2, 3, 4] — añade varios
Tuplas, conjuntos y diccionarios
4.1 · Tuplas: listas inmutables
Una tupla (tuple) se crea con paréntesis y es inmutable:
una vez creada no puedes añadir ni quitar elementos. Se usa para datos que no deben cambiar (coordenadas,
configuraciones, claves).
punto = (3, 4)
x, y = punto # desempacar: x=3, y=4
hyp = (punto[0] ** 2 + punto[1] ** 2) ** 0.5
print(f"Distancia al origen: {hyp:.2f}") # 5.00
a, b, c = [1, 2, 3] asigna cada nombre a
cada valor. Funciona con listas, tuplas y hasta con range. Es la forma elegante de «leer» una
colección fija.4.2 · Conjuntos: valores únicos
Un conjunto (set) almacena valores únicos y hace
operaciones matemáticas de conjuntos (unión, intersección…). Es la solución perfecta para «quitar
duplicados», y ninguna otra estructura es más rápida para comprobar pertenencia.
a = {1, 2, 3, 3, 3} # {1, 2, 3} — los duplicados desaparecen
b = {3, 4, 5}
print(a | b) # {1,2,3,4,5} — unión
print(a & b) # {3} — intersección
print(a - b) # {1,2} — diferencia
precio_unico = set([5, 5, 7, 9])
print(precio_unico) # {5, 7, 9} — cómo quitar duplicados
4.3 · Diccionarios: clave → valor
El diccionario (dict) es la estructura más importante de Python: asocia
claves únicas con valores. Es el equivalente a un objeto JSON o a un array
asociativo.
usuario = {
"nombre": "Ana",
"edad": 25,
"ciudad": "Madrid",
}
print(usuario["nombre"]) # Ana
usuario["edad"] = 26 # actualizar
usuario["email"] = "ana@x.es" # añadir (si la clave no existe)
print("nombre" in usuario) # True
print(usuario.get("telefono", "sin teléfono")) # sin teléfono → no da error
usuario["clave"] lanza KeyError si la clave no existe.
.get("clave", default) devuelve el valor por defecto sin lanzar error. En código moderno, usa
casi siempre .get().4.4 · Recorrer diccionarios
stock = {"camiseta": 12, "pantalón": 5, "gorra": 20}
for producto in stock: # itera sobre las claves
print(producto)
for producto, cantidad in stock.items(): # clave y valor a la vez
print(f"{producto}: {cantidad} uds")
| Tipo | Sintaxis | ¿Ordenado? | ¿Mutable? | ¿Duplicados? |
|---|---|---|---|---|
list | [1, 2] | Sí | Sí | Sí |
tuple | (1, 2) | Sí | No | Sí |
set | {1, 2} | No | Sí | No |
dict | {"a": 1} | Sí (inserción) | Sí | No (claves) |
Compresiones (comprehensions)
Una comprensión construye una colección en una sola línea: [expresión for x in
if condición]. Sustituye al patrón clásico de «crear lista vacía → for → append» y es un sello de
identidad de Python.
# Método clásico
cuadrados = []
for i in range(1, 6):
cuadrados.append(i ** 2)
# Comprensión (equivalente, en una línea)
cuadrados = [i ** 2 for i in range(1, 6)]
print(cuadrados) # [1, 4, 9, 16, 25]
5.1 · Con filtro
nums = list(range(0, 20))
pares = [n for n in nums if n % 2 == 0]
print(pares) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
cars = ["fi", "al", "alta"]
largas = [c.upper() for c in cars if len(c) >= 2]
5.2 · Compresión de diccionarios y de conjuntos
# dict: {clave: valor for ...}
cuadrados_dict = {i: i**2 for i in range(1, 4)}
print(cuadrados_dict) # {1: 1, 2: 4, 3: 9}
# set: {expresión for ...}
letras = {c for c in "abracadabra" if c not in "bd"}
print(letras) # {'a', 'r', 'c'} — únicas y filtradas
{str(i): v for i, v in enumerate(lista)} convierte una lista en un dict indexado por su
posición. La usarás en los ejercicios de esta semana.if o bucles anidados, usa un bucle normal: el código claro
gana a la línea corta.✍️ Los 14 ejercicios del bloque
Crea la carpeta python-b2/ y un archivo .py por ejercicio. Algunos piden
estructuras de datos fijas que definiremos aquí para que los ejercicios sean consistentes:
ventas = [120, 85, 200, 45, 90] y
alumnos = {"Ana": 8, "Luis": 6, "Rita": 9, "Pablo": 4}.
Sección A · Listas
1 Lista de compras dinámica
Crea una lista vacía. Pide 3 productos con input(), añádelos con append() y
muestra el resultado con print().
Ver solución
compras = []
for i in range(3):
compras.append(input(f"Producto {i+1}: "))
print(compras)
2 Los últimos 3 elementos
Dada ventas = [120, 85, 200, 45, 90], muestra los 3 últimos elementos con slicing y
calcula su suma con sum().
Ver solución
ventas = [120, 85, 200, 45, 90]
ultimas = ventas[-3:]
print(ultimas) # [200, 45, 90]
print(sum(ultimas)) # 335
3 Días con más de 100 €
Con la misma lista ventas, cuenta cuántos valores superan 100 usando una compresión de
listas y len().
Ver solución
ventas = [120, 85, 200, 45, 90]
altos = [v for v in ventas if v > 100]
print(len(altos)) # 2
4 Al revés
Dada nombres = ["Ana", "Luis", "Rita"], muestra la lista invertida usando slicing con paso
−1, y después ordénala alfabéticamente con sort().
Ver solución
nombres = ["Ana", "Luis", "Rita"]
print(nombres[::-1]) # ['Rita', 'Luis', 'Ana']
nombres.sort()
print(nombres) # ['Ana', 'Luis', 'Rita']
Sección B · Strings y tuplas
5 Palíndromo
Pide una palabra, pásala a minúsculas y comprueba si es un palíndromo comparándola con su versión
invertida ([::-1]). Muestra el resultado.
Ver solución
palabra = input("Palabra: ").lower()
if palabra == palabra[::-1]:
print("Es un palíndromo")
else:
print("No es un palíndromo")
6 Desempaquetado
Dada la tupla info = ("Ana", 25, "Madrid"), desempácala en tres variables y muéstralas con
una f-string.
Ver solución
info = ("Ana", 25, "Madrid")
nombre, edad, ciudad = info
print(f"{nombre}, {edad} años, de {ciudad}")
7 Sin duplicados
Dada numeros = [1, 2, 2, 3, 3, 3, 4], elimina los duplicados convirtiéndola en un
set y vuelve a lista. Muestra el resultado y cuántos elementos únicos hay.
Ver solución
numeros = [1, 2, 2, 3, 3, 3, 4]
unicos = list(set(numeros))
print(unicos) # [1, 2, 3, 4]
print(len(unicos)) # 4
8 Vocales en una frase
Pide una frase y cuenta cuántas vocales tiene recorriéndola y comprobando cada letra contra el conjunto
{"a","e","i","o","u"}. Útil para practicar in con sets.
Ver solución
vocales = {"a", "e", "i", "o", "u"}
frase = input("Frase: ").lower()
total = 0
for letra in frase:
if letra in vocales:
total += 1
print(f"Tiene {total} vocales")
Sección C · Diccionarios
9 Media de notas en un dict
Con alumnos = {"Ana": 8, "Luis": 6, "Rita": 9, "Pablo": 4}, calcula la media mediante
sum(alumnos.values()) / len(alumnos). Muestra el resultado con 2 decimales.
Ver solución
alumnos = {"Ana": 8, "Luis": 6, "Rita": 9, "Pablo": 4}
media = sum(alumnos.values()) / len(alumnos)
print(f"Media de la clase: {media:.2f}")
10 Aprobados y suspensos
Con el mismo dict alumnos, separa en dos listas los nombres con nota ≥ 5 y < 5, usando
compresiones de listas sobre alumnos.items().
Ver solución
alumnos = {"Ana": 8, "Luis": 6, "Rita": 9, "Pablo": 4}
aprobados = [n for n, nota in alumnos.items() if nota >= 5]
suspensos = [n for n, nota in alumnos.items() if nota < 5]
print(aprobados, suspensos)
11 Mejor y peor alumno
Con alumnos, encuentra el nombre con nota máxima y mínima usando max() y
min() con key=alumnos.get.
Ver solución
alumnos = {"Ana": 8, "Luis": 6, "Rita": 9, "Pablo": 4}
mejor = max(alumnos, key=alumnos.get)
peor = min(alumnos, key=alumnos.get)
print(f"Mejor: {mejor} ({alumnos[mejor]}), Peor: {peor} ({alumnos[peor]})")
12 Contador de letras
Pide una palabra y construye con una compresión de diccionarios un dict con cada letra y el número de
veces que aparece: {letra: palabra.count(letra) for letra in ...}.
Ver solución
palabra = input("Palabra: ")
frecuencias = {letra: palabra.count(letra) for letra in set(palabra)}
print(frecuencias) # por ejemplo {'h': 2, 'o': 1, ...}
13 Diccionarios anidados
Crea un dict de productos donde cada valor sea otro dict con precio y stock.
Muestra el precio del segundo producto y el total del inventario (suma de precio * stock).
Ver solución
tienda = {
"ratón": {"precio": 12, "stock": 30},
"teclado": {"precio": 25, "stock": 10},
"pantalla": {"precio": 150, "stock": 5},
}
print(tienda["teclado"]["precio"]) # 25
total = sum(p["precio"] * p["stock"] for p in tienda.values())
print(f"Valor total del inventario: {total} €")
14 🏆 Proyecto integrador: «gestor de inventario»
Crea inventario.py: un mini gestor con un diccionario de productos
({"camiseta": 12, "pantalón": 5, "gorra": 20}) y un menú infinito con while True:
- 1 · ver — muestra cada producto y su stock con
items(). - 2 · añadir — pide nombre y stock; usa
.get()para sumar al existente. - 3 · quitar — pide nombre y resta stock sin bajar de 0.
- 4 · total — muestra el stock total con
sum(values()). - salir — termina con
break. - Usa un
ifpara las opciones, comentarios#y nombres en snake_case.
Ver una solución posible
# Gestor de inventario con diccionarios
stock = {"camiseta": 12, "pantalón": 5, "gorra": 20}
while True:
print("\n--- INVENTARIO ---")
opcion = input("1 ver | 2 añadir | 3 quitar | 4 total | salir: ").strip().lower()
if opcion == "1": # ver inventario
for producto, cantidad in stock.items():
print(f"- {producto}: {cantidad} uds")
elif opcion == "2": # añadir stock
nombre = input("Producto: ")
cantidad = int(input("Cantidad: "))
stock[nombre] = stock.get(nombre, 0) + cantidad
elif opcion == "3": # quitar stock (sin bajar de 0)
nombre = input("Producto: ")
if nombre in stock:
stock[nombre] = max(stock[nombre] - int(input("Cantidad: ")), 0)
elif opcion == "4": # total de unidades
print(f"Stock total: {sum(stock.values())} uds")
elif opcion == "salir":
break
else:
print("Opción no válida")
📝 Examen del Bloque 2
Dos partes: un test teórico autoevaluable (mínimo 70 %) y un reto práctico de autocorrección con laboratorio.
Parte B · Reto «análisis de calificaciones»
Crea notas.py: dado un dict de alumnos y notas, muestra la media, quién aprueba y quién
suspende, y la mejor nota. Valida tú mismo/a estos criterios. Mínimo para aprobar: 6 de 8 casillas.
Cumplidos: 0 / 8