Saltar al contenido principal

Bloque 111. Colecciones: listas, tuplas, diccionarios y conjuntos

Contenidos

Revisa los siguientes apartados de la Unidad para resolver los ejercicios:

Ejercicio 1. Gestor de tareas pendientes

Programa un menú en bucle que gestione una lista de tareas en memoria:

  • Añadir una tarea (al final de la lista).
  • Marcar una tarea como completada (elimínala de la lista e imprime cuál era).
  • Mostrar las tareas pendientes, numeradas.
  • Salir.

Usa los métodos de lista que necesites (append, remove, indexación...).

💾 Haz un commit al terminar el ejercicio.

Ejercicio 2. Análisis de una frase

Pide al usuario una frase y, sin usar bucles explícitos donde no haga falta:

  • Muestra la frase invertida.
  • Cuenta cuántas palabras tiene (separa la frase en una lista de palabras).
  • Muestra solo las palabras de más de 4 letras, usando una comprensión de listas.

Apóyate en slicing y en los métodos de str, que comparten filosofía con los de listas.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 3. Agenda de contactos con diccionarios

Programa una agenda usando un diccionario donde la clave (key) es el nombre y el valor (value) es el número de teléfono.

El menú en bucle debe permitir:

  • Añadir un contacto: comprueba si el nombre ya existe usando el operador in sobre el diccionario. Si existe, actualiza su teléfono en vez de duplicarlo.
  • Buscar un contacto por nombre, usando el método .get() del diccionario. Muestra el mensaje "Contacto no encontrado" si no existe (en vez de que el programa falle con un error).
  • Eliminar un contacto.
  • Listar todos los contactos, ordenados alfabéticamente por nombre.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 4. De lista de diccionarios a resumen

Dada una lista de diccionarios (se debe declarar de forma literal), cada uno representando un alumno con las claves "nombre" y "nota":

alumnos = [
{"nombre": "Ana", "nota": 7.5},
{"nombre": "Luis", "nota": 4.2},
{"nombre": "Marta", "nota": 9.0},
]

Calcula y muestra: la nota media del grupo, el nombre de quien tiene la nota más alta, y una lista (con comprensión de listas) con los nombres de quienes han aprobado (nota ≥ 5).

💾 Haz un commit al terminar el ejercicio.

Ejercicio 5. Estadísticas de una lista de números

Pide al usuario 10 números, uno por uno, guardándolos en una lista.

Sin usar bucles propios donde no haga falta, muestra: el mayor, el menor, la media, y la lista ordenada de menor a mayor.

Después, usando sort() (el método de lista, no la función sorted()), ordénala también de mayor a menor y muéstrala de nuevo, para comprobar la diferencia entre ambos.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 6. Lista de la compra con cantidades

Programa una lista de la compra donde cada elemento es un diccionario {"producto": ..., "cantidad": ...} dentro de una lista.

El menú en bucle debe permitir:

  • Añadir un producto. Si ya existe, suma la cantidad en lugar de duplicarlo (tendrás que recorrer la lista para comprobarlo).
  • Eliminar un producto por nombre.
  • Mostrar la lista completa.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 7. Índice invertido

Dada una lista de frases cortas (defínelas como literal), construye un diccionario que, para cada palabra que aparezca en alguna frase, guarde una lista con los números de las frases en las que aparece (esto es la idea básica detrás de los motores de búsqueda).

Por ejemplo, si la palabra "gato" aparece en las frases 0 y 2, el diccionario debe tener "gato": [0, 2].

💾 Haz un commit al terminar el ejercicio.

Ejercicio 8. Diccionario de frecuencias

Pide al usuario una frase y, usando una comprensión de diccionarios, construye un diccionario que indique, para cada palabra distinta de la frase, cuántas veces aparece. Muestra el diccionario resultante.

Separa primero la frase en palabras con split(), obtén las palabras distintas con set(...) sobre esa lista, y construye el diccionario recorriendo ese conjunto con una comprensión que cuente cada palabra en la lista original con .count(...).

💾 Haz un commit al terminar el ejercicio.

Ejercicio 9. Refactor de tipo de colección

Pide al usuario una frase y sepárala en palabras con split(), pero guardando el resultado en una tupla en lugar de una lista (puedes convertir el resultado de split() a tupla con tuple(...)).

Comenta con # qué línea de código dejaría de funcionar si más adelante intentases modificar esa tupla (aunque no llegues a ejecutarla), y por qué.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 10. Coordenadas como tuplas

Escribe una función punto_medio(p1, p2) que reciba dos tuplas (x, y) y devuelva una nueva tupla con el punto medio entre ambas.

Pide al usuario las coordenadas de dos puntos (cuatro números en total), constrúyelas como tuplas, llama a la función y muestra el resultado desempaquetando la tupla devuelta en dos variables x e y. Es decir:

x, y = punto_medio(p1, p2)

💾 Haz un commit al terminar el ejercicio.

Ejercicio 11. Contar sin repetir

Dada una lista de literales con nombres de colores (con valores repetidos), usa un diccionario para contar cuántas veces aparece cada color, y compáralo con lo que obtendrías usando un set para saber solo qué colores distintos hay, sin cuántas veces.

Escribe, como comentario en el código, una frase explicando cuándo usarías el diccionario y cuándo el conjunto.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 12. Elige la colección adecuada

Para cada uno de los siguientes casos, indica si usarías una lista, una tupla, un conjunto o un diccionario, y justifica tu respuesta en una frase (no hace falta programarlo, solo razonar):

  1. Las coordenadas (x, y) de un punto en un mapa.
  2. El inventario de una tienda (producto → cantidad disponible).
  3. La lista de la compra de esta semana.
  4. Los días de la semana, para comprobar si un valor introducido por el usuario es uno de ellos.
  5. El histórico de puntuaciones de todas las partidas jugadas por un usuario.
  6. Los datos de configuración fijos de un programa (por ejemplo, ancho y alto de una ventana) que no deben poder modificarse por accidente.
  7. El conjunto de etiquetas (sin repetir) que un usuario ha asignado a una publicación.

💾 Haz un commit al terminar el ejercicio.

Algoritmos de ordenación

Python ya ordena listas por ti con sorted() y .sort(), pero implementar "a mano" los algoritmos de ordenación clásicos es un ejercicio muy habitual para practicar el razonamiento algorítmico con listas.

En los siguientes 5 ejercicios, no uses sorted() ni .sort(): la idea es programar tú mismo la lógica de ordenación.

Cada enunciado incluye una explicación breve, pero la explicación completa se puede encontrar en el apartado de contenidos.

Ejercicio 13. Bubble Sort

Bubble Sort ordena una lista comparando elementos adyacentes y intercambiándolos si están en el orden incorrecto, repitiendo este proceso hasta que no queden intercambios por hacer. En cada pasada completa, el elemento más grande "burbujea" hasta el final.

Escribe una función bubble_sort(lista) que devuelva una nueva lista ordenada de menor a mayor, implementando este algoritmo con bucles for anidados.

Prueba tu función con una lista de al menos 8 números desordenados.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 14. Insertion Sort

Insertion Sort construye la lista ordenada de izquierda a derecha: en cada paso, toma el siguiente elemento y lo inserta en su posición correcta dentro de la parte ya ordenada, desplazando los elementos mayores hacia la derecha.

Escribe una función insertion_sort(lista) que devuelva una nueva lista ordenada de menor a mayor usando este algoritmo.

Prueba tu función con la misma lista del ejercicio anterior y comprueba que da el mismo resultado.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 15. Selection Sort

Selection Sort busca, en cada vuelta, el elemento mínimo de la parte todavía no ordenada de la lista, y lo intercambia con el primer elemento de esa parte. Así, la parte ordenada (al principio de la lista) crece de uno en uno.

Escribe una función selection_sort(lista) que devuelva una nueva lista ordenada de menor a mayor usando este algoritmo.

Prueba tu función con la misma lista de los dos ejercicios anteriores.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 16. Merge Sort

Merge Sort sigue la estrategia divide y vencerás: divide la lista repetidamente por la mitad hasta llegar a sublistas de un solo elemento (que ya están "ordenadas" por definición), y después las va combinando (mezclando) de dos en dos, siempre en orden, hasta reconstruir la lista completa ordenada.

Escribe una función recursiva merge_sort(lista) que devuelva una nueva lista ordenada de menor a mayor. Puedes dividirla en dos con slicing (lista[:mitad] y lista[mitad:]), llamar recursivamente a merge_sort sobre cada mitad, y después combinar (merge) las dos mitades ya ordenadas comparando sus elementos uno a uno.

Prueba tu función con la misma lista de los ejercicios anteriores.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 17. Quick Sort

Quick Sort también sigue la estrategia divide y vencerás, pero de otra forma: elige un pivote (por ejemplo, el primer elemento de la lista), reorganiza el resto de elementos en dos grupos (los menores que el pivote y los mayores), y aplica el mismo proceso recursivamente a cada grupo. El pivote queda siempre en su posición final tras cada reparto.

Escribe una función recursiva quick_sort(lista) que devuelva una nueva lista ordenada de menor a mayor. Puedes usar comprensión de listas para construir los grupos de menores y mayores que el pivote.

Prueba tu función con la misma lista de los ejercicios anteriores.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 18. Diccionario inverso

Dado un diccionario (defínelo como literal en el código) que relaciona el código de un país con su nombre, construye un nuevo diccionario invertido, donde las claves pasan a ser los valores y viceversa.

Por ejemplo, dado:

{
"ES": "España",
"FR": "Francia",
"PT": "Portugal"
}

Se debe obtener:

{
"España": "ES",
"Francia": "FR",
"Portugal": "PT"
}

Recorre el diccionario original con .items() para construir el nuevo.

💾 Haz un commit al terminar el ejercicio.

Ejercicio 19. Fusión de inventarios

Dados dos diccionarios {"producto": cantidad, ...} que representan el inventario de dos tiendas de la misma cadena, construye un tercer diccionario con el inventario combinado. Los diccionarios originales se deben definir como literales.

Si un producto existe en las dos tiendas, se suman las cantidades de ambas tiendas. Si un producto solo existe en una de las dos, se mantiene su cantidad.

Usa el método .get() con valor por defecto 0 para no tener que comprobar antes si la clave ya existe.

💾 Haz un commit al terminar el ejercicio.

Repaso

Al terminar los ejercicios, debes tener claro los siguientes conceptos:

  • Definición y creación de listas
  • Mutabilidad de las listas
  • Indexación y slicing
  • Recorrer una lista con for
  • Métodos de lista (append, remove, sort...)
  • Comprensión de listas (list comprehensions)
  • Definición y creación de diccionarios
  • Añadir y modificar pares clave-valor
  • Acceso a un diccionario por clave
  • Operadores y métodos de diccionarios (in, .get()...)
  • Recorrer un diccionario (.items(), .keys(), .values())
  • Comprensión de diccionarios (dict comprehensions)
  • Representar una entidad del mundo real con un diccionario
  • Tuplas: creación e inmutabilidad
  • Desempaquetado de tuplas
  • Conjuntos (set): creación y ausencia de duplicados/orden
  • Criterios para elegir lista, tupla, conjunto o diccionario según el caso
  • Algoritmos de ordenación clásicos: Bubble Sort, Insertion Sort, Selection Sort
  • Algoritmos de ordenación con divide y vencerás: Merge Sort, Quick Sort
  • Invertir y fusionar diccionarios