Módulo 2: Estructuras de Datos y Funciones

Tema 6: Listas, Tuplas, Conjuntos y Diccionarios

Objetivo del tema:

Comprender y utilizar las estructuras de datos fundamentales de Python para almacenar, acceder y manipular colecciones de datos, y entender la diferencia entre tipos mutables e inmutables.

1. Listas (list)

Una lista es una colección ordenada y mutable de elementos. Puede contener cualquier tipo de dato (números, cadenas, objetos, etc.) y se define con corchetes: [].

Ejemplo:

Funciones comunes:

  • append(), remove(), insert(), pop(), sort(), reverse()
  • Slicing: frutas[1:3]

Slicing con las listas:

Es slicing (rebanado) de listas.

  • lista[inicio:fin] → devuelve una sublista desde inicio hasta fin - 1.
  • Si omites inicio, comienza desde el principio.
  • Si omites fin, va hasta el final.

Entonces:

  • numeros[1:] → devuelve la lista desde el índice 1 hasta el final, es decir, todos los elementos excepto el primero.

Ejemplo:

En una función recursiva:

  • numeros[0] → el primer elemento de la lista.
  • numeros[1:] → el resto de la lista (sin el primer elemento).

De este modo, en cada llamada recursiva la lista se va reduciendo hasta quedar vacía ([]), momento en el que se activa el caso base.

2. Tuplas (tuple)

Una tupla es una colección ordenada de elementos (como una lista), pero inmutable: no puedes modificarla después de crearla (ni agregar, ni quitar, ni cambiar elementos). Se define con paréntesis: ().

Uso típico: guardar datos que no deben cambiar (coordenadas, fechas, configuraciones, etc.). Ejemplo: coordenadas GPS (40.4168, -3.7038).

3. Conjuntos (set)

Un set es una colección desordenada de elementos únicos. Eso significa que:

  • No puede haber elementos repetidos.
  • El orden no está garantizado (no es como una lista o tupla).
  • Es mutable → puedes añadir o eliminar elementos.

Operaciones con set

Los set están pensados para trabajar con operaciones de conjuntos matemáticos:

Ejemplo práctico de uso:

4. Conjuntos inmutables (frozenset)

Un frozenset es como un conjunto (set), pero inmutable. Mientras que un set se puede modificar (agregar o quitar elementos), un frozenset no se puede cambiar después de su creación.

Uso típico:

  • Como clave en un diccionario (porque es inmutable).
  • Para representar conjuntos fijos de datos.

Ejemplo:

Resumen:

  • Tupla: lista inmutable, ordenada.
  • FrozenSet: conjunto inmutable, no ordenado.

5. Diccionarios (dict)

Un diccionario es una colección de pares clave-valor (no ordenada antes de Python 3.7; desde entonces mantiene el orden de inserción). Las claves deben ser únicas e inmutables (por ejemplo: strings, números, tuplas, frozensets). Los valores pueden ser de cualquier tipo (incluyendo listas, diccionarios, etc.).

Métodos comunes:

  • keys(), values(), items(), get(), pop()

Iterar sobre un diccionario

Diccionarios con tuplas como claves

Justo porque las tuplas son inmutables, Python permite usarlas como claves de un diccionario (en cambio una lista no puede, ya que puede cambiar y rompería la clave).

Otros ejemplos comunes de claves inmutables en diccionarios:

  • strings: {"nombre": "Ana"}
  • números: {1: "uno", 2: "dos"}
  • tuplas: {(1, 2): "punto en el plano"}

6. Mutables e inmutables

Tipos mutables

Son aquellos cuyo contenido sí puede cambiar después de crearlos. Ejemplo: listas (list), diccionarios (dict), conjuntos (set).

Tipos inmutables

Son aquellos cuyo contenido NO puede cambiar después de crearlos. Ejemplo: enteros (int), flotantes (float), booleanos (bool), cadenas (str), tuplas (tuple), frozenset.

¿Por qué existen los inmutables?

  1. Seguridad y consistencia → valores que no cambian facilitan el razonamiento (ejemplo: claves de diccionarios suelen ser inmutables).
  2. Eficiencia → Python puede reutilizar objetos inmutables en memoria en lugar de crear nuevos cada vez.
  3. Hashabilidad → los objetos inmutables pueden usarse como claves en diccionarios o elementos de un conjunto (set).

Resumen rápido:

  • Mutables → list, dict, set.
  • Inmutables → int, float, bool, str, tuple, frozenset.

Comparación: Mutables vs Inmutables

Tipo de dato Mutable/Inmutable Ejemplo de creación ¿Se puede modificar? Ejemplo de operación
list ✅ Mutable frutas = ["manzana", "pera"] frutas.append("naranja")["manzana", "pera", "naranja"]
dict ✅ Mutable persona = {"nombre": "Ana", "edad": 25} persona["edad"] = 26{"nombre": "Ana", "edad": 26}
set ✅ Mutable colores = {"rojo", "verde"} colores.add("azul"){"rojo", "verde", "azul"}
tuple Inmutable punto = (10, 20) No punto[0] = 30 → Error
str Inmutable texto = "hola" No texto.upper()"HOLA" (crea nueva cadena)
int Inmutable x = 5 No x += 1 → crea un nuevo 6, no cambia el 5
float Inmutable pi = 3.14 No pi * 2 → crea nuevo 6.28
bool Inmutable flag = True No not flag → crea False, no cambia True
frozenset Inmutable fs = frozenset([1, 2, 3]) No fs.add(4) → Error

En pocas palabras:

  • Usa mutables cuando quieras cambiar los datos en memoria (listas de items, diccionarios con valores dinámicos).
  • Usa inmutables cuando quieras asegurar que algo no cambie (claves de diccionarios, datos que deben ser constantes).

7. Comprensiones (comprehensions)

Una comprensión es una forma compacta de crear una colección a partir de otra (o de un range) en una sola línea, sustituyendo a un bucle con append.

Comprensión de lista:

Puedes añadir una condición con if para filtrar:

También funcionan con diccionarios y conjuntos:

Las comprensiones son muy idiomáticas en Python: más cortas y legibles que el bucle equivalente. No abuses de ellas si la lógica es compleja (en ese caso, un bucle normal se lee mejor).

Comparativa rápida:

Tipo Estructura Mutable Ordenado Acceso Permite duplicados
List Secuencia ordenada de elementos ✅ Sí Índices ✅ Sí
Tuple Secuencia ordenada inmutable No Índices ✅ Sí
Set Conjunto de elementos únicos ✅ Sí No No
FrozenSet Conjunto inmutable de elementos únicos No No No
Dict Pares clave → valor (ordenados desde Python 3.7) ✅ Sí Claves No (en claves)

Diferencia clave:

  • list, tuple, set, frozenset → almacenan valores.
  • dict → almacena pares clave-valor

Regla rápida para recordar:

  • Usa lista si necesitas un array que puedas modificar.
  • Usa tupla si los datos son fijos (ejemplo: coordenadas).
  • Usa set si necesitas eliminar duplicados o trabajar con teoría de conjuntos.
  • Usa frozenset si necesitas un conjunto inmutable (ejemplo: clave en diccionarios).

Actividades sugeridas:

  1. Crea una lista de tus comidas favoritas, ordénala y elimina un elemento.
  2. Representa una fecha de nacimiento con una tupla.
  3. Usa un conjunto para guardar colores favoritos sin repetir.
  4. Crea un diccionario con datos de una persona y muestra sus claves y valores.
  5. Crea un diccionario que use tuplas (coordenadas) como claves y recórrelo con .items().
  6. Comprueba en código qué tipos son mutables e inmutables probando a modificar una lista, una tupla, un set y un frozenset.

Tema 7: Funciones — Definición, Argumentos y Retorno

Objetivo del tema:

Comprender qué son las funciones en Python, cómo se definen, cómo se pasan argumentos y cómo se devuelve un valor. Se busca fomentar la reutilización de código y la organización modular.

¿Qué es una función?

Una función es un bloque de código reutilizable que se ejecuta solo cuando se llama. Se usa para organizar programas y evitar la repetición.

Sintaxis básica:

1. Definición de una función

2. Argumentos (Parámetros)

Puedes pasar datos a una función a través de argumentos.

Tipos de argumentos:

  • Posicionales
  • Por defecto
  • Arbitrarios (*args)
  • Clave-valor (**kwargs)

Ejemplo con valores por defecto:

Ejemplo con argumentos arbitrarios (*args):

Recibe un número indeterminado de argumentos posicionales, agrupados en una tupla.

Ejemplo con argumentos clave-valor (**kwargs):

Recibe un número indeterminado de argumentos con nombre, agrupados en un diccionario.

3. Valor de retorno (return)

Una función puede devolver un valor con la palabra clave return.

4. Funciones lambda (anónimas)

Una función lambda es una función pequeña y sin nombre que se escribe en una sola línea. Es útil para operaciones simples, sobre todo como argumento de otras funciones.

Su uso más habitual es pasarla como parámetro key a funciones como sorted():

Para lógica más compleja, define una función normal con def: es más legible.

Buenas prácticas

  • Las funciones deben tener un solo propósito.
  • Usar nombres descriptivos.
  • Documentar con comentarios o docstrings.

Actividades sugeridas:

  1. Crear una función que reciba una edad y devuelva si es mayor o menor de edad.
  2. Crear una función que calcule el área de un triángulo.
  3. Crear una función que reciba una lista de números y devuelva la suma total.
  4. Crear una función con *args que imprima todos los argumentos que se le pasen.
  5. Crear una función que reciba un diccionario y devuelva las claves y valores separados.

Tema 8: Alcance de Variables. Introducción a la Recursividad

Objetivo del tema:

Comprender cómo funciona el alcance (scope) de las variables en Python y realizar una introducción a la recursividad como técnica de resolución de problemas.

1. Alcance de Variables (Variable Scope)

El alcance de una variable determina dónde puede ser utilizada.

Tipos de alcance:

  • Local: definida dentro de una función.
  • Global: definida fuera de cualquier función.
  • Nonlocal: para modificar variables de un entorno intermedio (en funciones anidadas).

Ejemplo de variable local:

Ejemplo de variable global:

Usando global:

Buena práctica: Evitar modificar variables globales dentro de funciones.

2. Introducción a la Recursividad

La recursividad es una técnica donde una función se llama a sí misma para resolver un problema.

Requisitos básicos:

  • Caso base (condición para detener la recursión).
  • Llamada recursiva.

Ejemplo: Factorial de un número

Ejemplo: Números de Fibonacci

Precauciones con recursividad

  • Puede causar errores de memoria si no se controla.
  • Python tiene un límite de profundidad recursiva (por defecto, 1000).

Actividades sugeridas:

  1. Crear una función recursiva que calcule el producto de una lista de números.
  2. Crear una función recursiva que cuente regresivamente desde un número.
  3. Crear una función recursiva que calcule la suma de los números desde 1 hasta n.
  4. (CASA) -> Crear una función recursiva que devuelva cuántos dígitos tiene un número entero positivo., str() -> lo que sea a string
  5. 123 -> 3
  6. 123213 -> 6
  7. (CASA) -> Escribir ejemplos propios de funciones que utilicen variables globales, locales y nonlocal.

Tema 9: Documentación y Buenas Prácticas en Python

Objetivo del tema:

Aprender a documentar el código adecuadamente utilizando comentarios y docstrings, así como conocer y aplicar las buenas prácticas de codificación en Python, incluyendo la guía de estilo PEP 8.

1. Comentarios en Python

  • Los comentarios sirven para explicar el código a otros (¡y a ti en el futuro!).
  • Se ignoran durante la ejecución del programa.

2. Docstrings (Documentación interna)

Los docstrings describen el propósito de un módulo, clase o función. Se colocan justo debajo de la definición.

Importante: Python utiliza estos docstrings para herramientas como help() o generadores de documentación.

3. Buenas prácticas de codificación

Seguir un estilo limpio y coherente mejora la legibilidad y el mantenimiento del código. Python propone la guía PEP 8 como estándar.

Algunas reglas clave de PEP 8:

  • Usa 4 espacios por nivel de indentación.
  • Nombres de variables descriptivos (total_factura, no tf).
  • Líneas de máximo 79 caracteres.
  • Usa espacios alrededor de los operadores.

Nombres de funciones y variables

  • snake_case para funciones y variables: calcular_precio_total
  • PascalCase para clases: FacturaMensual

Importaciones

  • Colocar todas las importaciones al inicio del archivo.
  • Separar con líneas en blanco: estándar, terceros y locales.

Código limpio y modular

  • Reutilizar funciones.
  • Evitar duplicación de código.
  • Evitar funciones muy largas.

4. Herramientas útiles

  • flake8: Linter para verificar errores de estilo.
  • black: Formateador automático de código.
  • pydoc: Generador de documentación basado en docstrings.

Actividades sugeridas

  1. Añadir docstrings a varias funciones sin documentación.
  2. Revisar un fragmento de código y aplicar mejoras según PEP 8.
  3. Identificar malas prácticas y corregirlas.
  4. Utilizar flake8 (si se permite instalar) para revisar estilo.
  5. Documentar completamente un pequeño módulo (2 o 3 funciones).