class: center, middle, inverse, title-slide .title[ #
Introducción a Python
] .subtitle[ ##
Clase 3: Estructura de Datos
] .author[ ### Daniel Miles Touya
Máster en Análisis de Datos · UdelaR-Uvigo
] .date[ ### 27 abril 2026 ] --- class: inverse, middle .huge[Clase 3] <br> ## Estructuras de datos --- # Guía de lectura de la clase .smallest[ En la clase anterior vimos: - todo en Python es un objeto - las variables son etiquetas - los objetos tienen tipo, identidad y valor ] -- .div_bloque[ En esta clase veremos **objetos** que pueden <b>contener</b> otros **objetos**. ] -- .smallest[ Es decir, estructuras que sirven para **organizar información**: - listas (list) - tuplas (tuple) - diccionarios (dictionary) - conjuntos (set) ] --- # La idea central .div_bloque[ Algunas estructuras de Python son .hi-red[containers]. ] -- .smallest[ Un container es un objeto que contiene referencias a otros objetos. > Es posible extraer los objetos de ese container: indexar los objetos para extraerlos del contenedor ] -- ```python lista = [10, 20, 30] print(lista) print(type(lista)) ``` -- .div_bloque.small[ La lista no “guarda valores” como cajas independientes. Guarda referencias a objetos. ] --- # Secuencias .div_bloque[ Una secuencia es un container ordenado. ] -- .smallest[ En una secuencia, cada elemento tiene una posición. ] -- ```python ventas = [100, 200, 150, 300] print(ventas[0]) print(ventas[1]) print(ventas[2]) ``` -- .smallest[ Pregunta: > ¿por qué el primer elemento está en la posición `0`? ] --- # Python empieza a contar en cero .div_bloque[ En Python, el primer índice es `0`. ] -- ```python ciudad = "Madrid" print(ciudad[0]) print(ciudad[1]) print(ciudad[2]) ``` -- .smallest[ Lectura: - `ciudad[0]` devuelve el primer carácter - `ciudad[1]` devuelve el segundo - `ciudad[2]` devuelve el tercero ] --- # Índices negativos .div_bloque[ Los índices negativos cuentan desde el final. ] -- ```python ventas = [100, 200, 150, 300] print(ventas[-1]) print(ventas[-2]) ``` -- .smallest[ Esto es muy útil cuando no sabemos cuántos elementos tiene una secuencia. ] --- # Longitud de una secuencia .div_bloque[ La función `len()` devuelve cuántos elementos tiene una secuencia. ] -- ```python ventas = [100, 200, 150, 300] print(len(ventas)) print(ventas[len(ventas) - 1]) print(ventas[-1]) ``` -- .smallest[ Las dos últimas líneas devuelven el último elemento. Pero `ventas[-1]` es más fácil de leer. ] --- # Slicing .div_bloque[ El slicing permite extraer una parte de una secuencia. ] -- ```python meses = ["ene", "feb", "mar", "abr", "may", "jun"] print(meses[1:4]) print(meses[:3]) print(meses[3:]) ``` -- .smallest[ Regla clave: > en `meses[1:4]`, el índice `1` entra, pero el índice `4` no entra. ] --- # El stop no se incluye .div_bloque[ Esta es una de las reglas más importantes del slicing. ] -- ```python meses = ["ene", "feb", "mar", "abr", "may", "jun"] print(meses[1:4]) ``` -- .smallest[ Resultado: ```python ["feb", "mar", "abr"] ``` ] -- .div_bloque.small[ .hi-red[Idea:] `start` se incluye. `stop` se excluye. ] --- # Invertir una secuencia .div_bloque[ El slicing también permite cambiar el paso. ] -- ```python texto = "Python" print(texto[::-1]) ``` -- .smallest[ Este patrón aparece mucho en código Python: ```python [::-1] ``` Significa: > toma toda la secuencia, pero en orden inverso. ] --- # Slicing crea un objeto nuevo .div_bloque[ Cuando hacemos slicing, Python crea una nueva secuencia. ] -- ```python original = [1, 2, 3, 4, 5] trozo = original[1:4] print(original) print(trozo) print(original is trozo) ``` -- .smallest[ Pregunta: > ¿`original` y `trozo` son el mismo objeto? ] --- # Modificar el trozo .smallest[ Ahora modificamos el trozo: ] ```python original = [1, 2, 3, 4, 5] trozo = original[1:4] trozo[0] = 99 print(original) print(trozo) ``` -- .div_bloque.small[ .hi-blue[Idea:] Modificar `trozo` no modifica `original`, porque el slicing creó una lista nueva. ] --- # Operaciones comunes .smallest[ Muchas operaciones funcionan sobre cualquier secuencia. ] ```python lista = [3, 1, 4, 1, 5] texto = "Mississippi" print(len(lista)) print(1 in lista) print(lista.count(1)) print(len(texto)) print("ss" in texto) print(texto.count("s")) ``` -- .div_bloque.small[ Leer código Python exige reconocer estas operaciones básicas. ] --- # Qué debes recordar .smallest[ En esta primera parte de la lectura, fíjate especialmente en: - qué es una secuencia - cómo funciona la indexación - por qué Python empieza en `0` - qué significa que el `stop` del slicing no se incluya - qué devuelve `len()` - cómo leer `[::-1]` ] -- .div_bloque[ .hi-blue[Idea final:] > Una secuencia es una estructura ordenada que podemos leer por posiciones. ] --- # List .smallest[Una der las estructura de datos más usada] -- .smallest[ Una lista es una secuencia mutable. ] -- .smallest[ - es ordenada - permite duplicados - se puede modificar ] -- ```python lista = [10, 20, 30] print(lista) print(type(lista)) ``` --- # Crear listas .smallest[ Podemos crear listas con distintos tipos de objetos. ] -- ```python lista = [1, "hola", 3.5, True] print(lista) ``` -- .div_bloque.small[ Una lista puede contener objetos de distintos tipos. ] --- # Acceder a elementos .smallest[ Usamos indexación como en cualquier secuencia. ] -- ```python lista = [10, 20, 30, 40] print(lista[0]) print(lista[2]) print(lista[-1]) ``` --- # Modificar una lista .div_bloque[ Las listas son mutables. ] -- ```python lista = [10, 20, 30] lista[0] = 99 print(lista) ``` -- .smallest[ Pregunta: > ¿cambia el objeto o se crea uno nuevo? ] --- # Añadir elementos .smallest[ Podemos añadir elementos al final. ] -- ```python lista = [1, 2, 3] lista.append(4) print(lista) ``` -- .div_bloque.small[ `append()` modifica la lista existente. ] --- # Añadir varios elementos .smallest[ También podemos añadir varios elementos. ] -- ```python lista = [1, 2, 3] lista.extend([4, 5]) print(lista) ``` -- .smallest[ Diferencia: - `append()` añade un elemento - `extend()` añade varios ] --- # Insertar elementos .smallest[ Podemos insertar en una posición concreta. ] -- ```python lista = [1, 2, 3] lista.insert(1, 99) print(lista) ``` -- .smallest[ `insert(posición, valor)` ] --- # Eliminar elementos .smallest[ Hay varias formas de eliminar elementos. ] -- ```python lista = [1, 2, 3, 4] lista.remove(2) print(lista) lista.pop() print(lista) ``` -- .div_bloque.small[ - `remove()` elimina por valor - `pop()` elimina el último elemento ] --- # Longitud de la lista .smallest[ Podemos contar cuántos elementos hay. ] -- ```python lista = [1, 2, 3, 4, 5] print(len(lista)) ``` --- # Buscar elementos .smallest[ Podemos comprobar si un elemento está en la lista. ] -- ```python lista = [10, 20, 30] print(20 in lista) print(50 in lista) ``` --- # Recorrer una lista (lectura básica) .smallest[ Aparece mucho en código real: ] ```python lista = [10, 20, 30] for x in lista: print(x) ``` -- .div_bloque.small[ No necesitas dominar `for` todavía **lo veremos mas adelante**, pero debes inteerpretar lo que hace. > Debe empezar a reconocer qué está haciendo. ] --- # Error típico .smallest[ Acceder a una posición que no existe: ] ```python lista = [1, 2, 3] print(lista[5]) ``` -- .div_bloque.small[ .hi-red[Resultado:] `IndexError` ] -- .div_bloque.small[ .hi-red[Observar] la descripcion del error...pues cada error dará lugar a descripciópn distinta ] --- # Qué debes entender .smallest[ En el material, fíjate en: - que las listas son mutables - cómo se modifican - qué hacen `append`, `extend`, `insert` - cómo se eliminan elementos - cómo detectar errores ] -- .div_bloque[ .hi-blue[Idea final:] > Una lista es la estructura básica para trabajar con colecciones de datos. ] --- # Tuple .hi-blue[Tuple]: Secuencias inmutables -- > Qué es una tupla >> .div_bloque[ Una tupla es una secuencia inmutable. ] -- .smallest[ - es ordenada - permite duplicados - no se puede modificar ] -- ```python tupla = (10, 20, 30) print(tupla) print(type(tupla)) ``` --- # Diferencia clave con listas .div_bloque[ La diferencia fundamental es la mutabilidad. ] -- ```python lista = [1, 2, 3] tupla = (1, 2, 3) lista[0] = 99 print(lista) tupla[0] = 99 ``` -- .div_bloque.small[ .hi-red[Resultado:] `TypeError` ] --- # Por qué usar tuplas .smallest[ Las tuplas se usan cuando los datos no deben cambiar. ] -- ```python coordenadas = (10.5, 20.3) print(coordenadas) ``` -- .div_bloque.small[ Ejemplo típico: - coordenadas - fechas - parámetros fijos ] --- # Acceso a elementos .smallest[ Funcionan igual que otras secuencias. ] -- ```python tupla = (10, 20, 30, 40) print(tupla[0]) print(tupla[-1]) ``` --- # Slicing en tuplas .smallest[ También podemos hacer slicing. ] -- ```python tupla = (10, 20, 30, 40) print(tupla[1:3]) ``` -- .smallest[ Pero el resultado sigue siendo una tupla. ] --- # Una tupla de un elemento .div_bloque[ Esto es un error muy común. ] -- ```python x = (5) print(type(x)) ``` -- ```python x = (5,) print(type(x)) ``` -- .div_bloque.small[ .hi-red[Idea:] La coma define la tupla, no los paréntesis. ] --- # Desempaquetado .smallest[ Podemos asignar varios valores a la vez. ] -- ```python tupla = (10, 20) x, y = tupla print(x) print(y) ``` -- .div_bloque.small[ Esto aparece mucho en código real. ] --- # Unpacking -desempaquetado: Uso en bucles .smallest[ Es común en estructuras como listas de tuplas. ] -- ```python datos = [("Ana", 8), ("Luis", 7), ("Marta", 9)] for nombre, nota in datos: print(nombre, nota) ``` -- .div_bloque.small[ No necesitas dominarlo aún, pero sí reconocerlo. ] --- # Tuplas y funciones .smallest[ Muchas funciones devuelven tuplas. ] -- ```python def dividir(a, b): return a // b, a % b resultado = dividir(10, 3) print(resultado) ``` -- .smallest[ Esto es muy común en Python. ] --- # Qué debes entender .smallest[ En el material, fíjate en: - qué significa que una tupla sea inmutable - cuándo usar tuplas en lugar de listas - cómo leer errores de tipo - cómo funciona el desempaquetado ] -- .div_bloque[ .hi-blue[Idea final:] > Una tupla es una secuencia fija: útil cuando los datos no deben cambiar. ] --- # Dictionary .hi-blue[Dictionary]: **Clave → valor** (Key, value) -- > Qué es un diccionario >> .div_bloque[ Un diccionario es una estructura de datos basada en claves (keys). ] -- .smallest[ - cada elemento tiene una clave - cada clave apunta a un valor - no hay duplicados de claves ] -- ```python alumno = {"nombre": "Ana", "nota": 8.5} print(alumno) print(type(alumno)) ``` --- # Acceso por clave .div_bloque[ No usamos índices, usamos claves. ] -- ```python alumno = {"nombre": "Ana", "nota": 8.5} print(alumno["nombre"]) print(alumno["nota"]) ``` -- .smallest[ Pregunta: > ¿qué pasa si la clave no existe? ] --- # Error típico .smallest[ Acceder a una clave que no existe: ] ```python alumno = {"nombre": "Ana"} print(alumno["edad"]) ``` -- .div_bloque.small[ .hi-red[Resultado:] `KeyError` ] --- # Añadir elementos .smallest[ Podemos añadir nuevos pares clave → valor. ] -- ```python alumno = {"nombre": "Ana"} alumno["edad"] = 25 print(alumno) ``` -- .div_bloque.small[ Si la clave no existe → se crea ] --- # Modificar valores .smallest[ Si la clave ya existe, se actualiza el valor. ] -- ```python alumno = {"nombre": "Ana", "nota": 7} alumno["nota"] = 9 print(alumno) ``` --- # Eliminar elementos .smallest[ Podemos eliminar claves. ] -- ```python alumno = {"nombre": "Ana", "nota": 8} del alumno["nota"] print(alumno) ``` --- # Comprobar si existe una clave .smallest[ Antes de acceder, podemos comprobar si existe. ] -- ```python alumno = {"nombre": "Ana"} print("nombre" in alumno) print("edad" in alumno) ``` -- .div_bloque.small[ Esto evita errores. ] --- # Método get() .div_bloque[ Una forma más segura de acceder. ] -- ```python alumno = {"nombre": "Ana"} print(alumno.get("nombre")) print(alumno.get("edad")) ``` -- .smallest[ Si la clave no existe, devuelve `None` en lugar de error. ] --- # Recorrer un diccionario .smallest[ Podemos recorrer claves y valores. ] -- ```python alumno = {"nombre": "Ana", "nota": 8} for clave in alumno: print(clave, alumno[clave]) ``` -- .div_bloque.small[ Aparece mucho en código real. ] --- # Uso típico en datos .smallest[ Un diccionario representa una observación. ] -- ```python alumno = {"nombre": "Ana", "edad": 25, "nota": 8.5} print(alumno["nota"]) ``` -- .smallest[ En data analysis: - columnas → claves - valores → datos ] --- # Diccionarios y listas .smallest[ Muy común: lista de diccionarios. ] -- ```python datos = [ {"nombre": "Ana", "nota": 8}, {"nombre": "Luis", "nota": 7} ] print(datos[0]["nombre"]) ``` -- .div_bloque.small[ Este patrón aparece mucho en código de IA y APIs. ] --- # Qué debes entender .smallest[ En el material, fíjate en: - qué es una clave - cómo acceder a valores - qué errores pueden aparecer - cuándo usar `get()` - cómo se usan en datos reales ] -- .div_bloque[ .hi-blue[Idea final:] > Un diccionario organiza información mediante claves en lugar de posiciones. ] --- # Set: conjunto .hi-blue[Set]: sin orden, sin duplicados -- > Qué es un set >> .div_bloque[ Un set es una colección de elementos únicos. ] -- .smallest[ - no tiene orden - no permite duplicados - es mutable ] -- ```python s = {1, 2, 3} print(s) print(type(s)) ``` --- # Sin duplicados .smallest[ Los elementos repetidos se eliminan automáticamente. ] -- ```python s = {1, 2, 2, 3, 3, 3} print(s) ``` -- .div_bloque.small[ .hi-blue[Idea:] Un set siempre contiene elementos únicos. ] --- # Crear sets .smallest[ También podemos crear sets a partir de listas. ] -- ```python lista = [1, 2, 2, 3, 3, 3] s = set(lista) print(s) ``` -- .div_bloque.small[ Esto es muy común para eliminar duplicados. ] --- # Añadir elementos .smallest[ Podemos añadir elementos a un set. ] -- ```python s = {1, 2, 3} s.add(4) print(s) ``` --- # Eliminar elementos .smallest[ Podemos eliminar elementos. ] -- ```python s = {1, 2, 3} s.remove(2) print(s) ``` --- # Comprobar pertenencia .div_bloque[ El uso principal de los sets es comprobar pertenencia. ] -- ```python s = {10, 20, 30} print(20 in s) print(50 in s) ``` -- .smallest[ Esto es más eficiente que en listas. ] --- # No hay índices .div_bloque[ Un set no tiene orden. ] -- ```python s = {1, 2, 3} print(s[0]) ``` -- .div_bloque.small[ .hi-red[Resultado:] `TypeError` ] --- # Operaciones entre sets .smallest[ Podemos combinar sets. ] -- ```python a = {1, 2, 3} b = {3, 4, 5} print(a | b) # unión print(a & b) # intersección ``` -- .div_bloque.small[ Estas operaciones aparecen en código real. ] --- # Uso típico .smallest[ Eliminar duplicados: ] ```python datos = [1, 2, 2, 3, 3, 3] unicos = set(datos) print(unicos) ``` -- .smallest[ Comprobar si un elemento está: ] ```python print(2 in unicos) ``` --- # Qué debes entender .smallest[ En el material, fíjate en: - que un set no tiene orden - que elimina duplicados automáticamente - que no se puede indexar - que se usa para comprobar pertenencia ] -- .div_bloque[ .hi-blue[Idea final:] > Un set es la herramienta más simple para trabajar con elementos únicos. ] --- # Lectura dle html Aquí acabamos la guía de lo que encontrarán en vuestro hmtl de esta clase...a trabajar despacio, intentando usar los modelos de lenguage como elementos de consulta.