# Con las estructuras de datos es muy normal tener elementos anidados alumnos = [{ "nombre": "Ana", "email": "ana@ana.com", "notas": [{"asignatura": "Python", "nota": 6}, {"asignatura": "Java", "nota": 8}, {"asignatura": "C#", "nota": 5}] }, { "nombre": "Eva", "email": "eva@eva.com", "notas": [{"asignatura": "Python", "nota": 8}, {"asignatura": "Java", "nota": 1}, {"asignatura": "C#", "nota": 5}] }, { "nombre": "Pep", "email": "pep@pep.com", "notas": [{"asignatura": "Python", "nota": 4}, {"asignatura": "Java", "nota": 5}, {"asignatura": "C#", "nota": 5}] }] # En primer lugar estoy recorriendo la lista de alumnos for alumno in alumnos: print("Alumno: ", alumno["nombre"]) total = 0 # Recorro la lista que está en la propiedad 'notas' for nota in alumno["notas"]: total += nota["nota"] # recorro el diccionario de cada una de las notas for clave, valor in nota.items(): print(clave, valor) print("Media", total / len(alumno["notas"])) print("-" * 20) # En primer lugar estoy recorriendo la lista de alumnos for alumno in alumnos: print("Alumno: ", alumno["nombre"]) total = 0 # Recorro la lista que está en la propiedad 'notas' for nota in alumno["notas"]: total += nota["nota"] # recorro el diccionario de cada una de las notas for clave, valor in nota.items(): print(clave, valor) print("Media", total / len(alumno["notas"])) print("-" * 20) # SI quisiera saber la media de notas de cada asignatura ¿Cómo lo haría? # Creo un diccionario cuya clave sea la asignatura y el valor las notas # Primero creo un diccionario vacío asignaturas={} # Recorro los alumnos for alumno in alumnos: # Recorro las asignaturas de los alumnos for asignatura in alumno["notas"]: nombre=asignatura["asignatura"] # capturo el nombre nota=asignatura["nota"] # capturo la nota print(nombre,nota) # Imprimo para probar # Compruebo si es la primera vez que tengo esta asignatura # Si es la primera vez no está en el diccionario if nombre not in asignaturas: asignaturas[nombre]=[] # entonces me creo una lista vacía # Añado la nota a esa lista asignaturas[nombre].append(nota) # Tengo un diccionario que he creado yo con la clave el nombre de la asignatura # Los valores las notas de cada asignatura print(asignaturas) # Teniendo ese diccionario sacar la media es trivial for nombre,notas in asignaturas.items(): print(nombre,sum(notas)/len(notas))
Autor: Juan Pablo Fuentes
Formador de programación y bases de datos
Diccionarios
# Un diccionario es una estructura de datos que se basa en # un par clave, valor # Es decir, tenemos una serie de elementos identificados por una clave # y para cada clave tenemos un valor # lista de alumnos y una lista de notas alumnos = ["Ana", "Eva", "Pep1"] notas = [6, 7, 8] # para definir un diccionario utilizo las llaves {} # conjunto de pares 'clave' y 'valor' alumno1 = { "nombre": "Ana", # clave es 'nombre' y el valor 'Ana' "nota": 6 # clave es 'nota' y el valor 6 } print(alumno1) # como accedo yo a los valores inviduales. mediante la clave print(alumno1["nombre"]) print(alumno1["nota"]) print(alumno1.get("nota")) print(alumno1.get("notas", 0)) # si la clave no existe podemos tener un valor por defecto alumno1["email"] = "ana@ana.com" print(alumno1) alumno1["nota"] = 9 # cambio el valor de esa clave print(alumno1) alumno2 = {"nombre": "Eva", "nota": 8, "nombre": "Pep" # Las claves no pueden estar repetidas. En este caso se sustituye el valor anterior } print(alumno2) # eliminar elementos del diccionario con 'pop' alumno1.pop("email") # elimina la clave 'email' print(alumno1) alumno1.popitem() # elimina la última clave print(alumno1) # En python tenemos 'del' para eliminar cualquier variable del alumno1["nombre"] # nos elimina la clave 'nombre' print(alumno1) del alumno1 # nos dejaría si esta variable alumno2.clear() # vaciar un diccionario alumno2 = {"nombre": "Eva", "nota": 8, "Apellido": "Pi", "email": "eva@eva.com" } # recorrer un diccionario for elemento in alumno2: print(elemento) # recorre las claves del diccionario # Con esto recorro tanto las claves como los valores for elemento in alumno2: print(elemento, alumno2[elemento],alumno2.get(elemento)) # recorre las claves del diccionario # Con esto recorro solo los valores for elemento in alumno2.values(): print(elemento) # recorre solo los valores print(alumno2.keys()) # recorro los items que son tuplas y la desempaqueto y la asigno a una clave y un valor for clave, valor in alumno2.items(): print(clave, valor) print(alumno2.items()) # Copiar un diccionario igual que una lista, con copy alumno3 = alumno2.copy() alumno3["nombre"] = "Juan" print(alumno3) # Comprobar que la clave exista if "nombre" in alumno3: print(alumno3["nombre"]) # Comprobar que el valor existe if "Juan" in alumno3.values(): print("Juan es un valor del diccionario")
Ejercicio
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Visitantes</title> <link rel="stylesheet" href="css/estilos.css"> <!-- Latest compiled and minified CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- Latest compiled JavaScript --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="container-fluid "> <div class="row"> <div class="col"> <h1 class="display-3 ">Control de visitantes</h1> <button id="add" class="btn btn-success ">Añadir visitante</button> <div class="form-check"> <input class="form-check-input" type="checkbox" id="reutilizar" name="reutilizar" value="something" checked> <label class="form-check-label" for="reutilizar">Reutilizar números</label> </div> </div> </div> <div class="row"> <div class="col"> <h1 class="display-4 ">Visitantes</h1> <div id="visitantes"></div> </div> <div class="col"> <h1 class="display-4 ">Histórico</h1> <div id="historico"></div> </div> </div> </div> <script src="js/script.js"></script> </body> </html>
.numero{ display: inline-block; border:2px solid blue; padding: 5px; min-width: 2em; font-size: 2em; text-align: center; font-weight: bold; margin: 10px; }
estado = {} window.onload = function () { estado.lista = []; estado.historico = []; estado.actual = 1; estado.limite = 20; estado.add = document.getElementById("add"); estado.add.addEventListener("click", addVisitante); estado.visitantes = document.getElementById("visitantes"); estado.historicos = document.getElementById("historico"); estado.reutilizar = document.getElementById("reutilizar"); iniciar(); } function iniciar() { pintarLista(); } function addVisitante() { if (estado.reutilizar.checked) { // Buscar el primer elemento libre de la lista let numero = 1; while (estado.lista.includes(numero)) { numero++; } estado.lista.push(numero); estado.lista.sort((a,b)=>a-b) } else { estado.lista.push(estado.actual); estado.actual++; } pintarLista(); } function checkAdd() { if (estado.lista.length <= estado.limite) { estado.add.classList.remove("disabled") } else { estado.add.classList.add("disabled") } } function pintarLista() { checkAdd(); pintarDatos(estado.lista, estado.visitantes); pintarDatos(estado.historico, estado.historicos); } function pincharCaja() { let numero = Number(this.innerHTML); estado.historico = estado.historico.concat(estado.lista.filter(x => x == numero)) if (estado.historico.length>estado.limite){ estado.historico=estado.historico.slice(-estado.limite); } estado.lista = estado.lista.filter(x => x != numero); pintarLista(); } function esPrimo(numero){ for(let i=2;i<=Math.sqrt(numero);i++){ if (numero%i==0){ return false; } } return true; } function pintarDatos(datos, destino) { destino.innerHTML = "" for (let elemento of datos) { let caja = document.createElement("div"); caja.innerHTML = elemento; caja.classList.add("numero"); if (esPrimo(elemento)){ caja.classList.add("bg-warning"); } caja.addEventListener("click", pincharCaja); destino.append(caja) } }
Solución ejercicio examen
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Bolsa de horas</title> <!-- Latest compiled and minified CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- Latest compiled JavaScript --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-4 "> <form> <h3 class="mt-5 ">Datos del pedido</h3> <div class="mb-3 mt-3"> <label for="cliente" class="form-label">Cliente:</label> <input type="text" class="form-control" id="cliente" placeholder="Introduzca el nombre del cliente" name="cliente"> </div> <div class="mb-3"> <label for="horas" class="form-label">Horas:</label> <input type="number" class="form-control" id="horas" placeholder="Introduzca las horas" name="horas"> </div> <div class="btn-group mb-3"> <button type="button" class="btn btn-primary tipoEmpleado">Junior</button> <button type="button" class="btn btn-primary tipoEmpleado">Senior</button> <button type="button" class="btn btn-primary tipoEmpleado">Master</button> </div> <div> <button id="addPedido" type="button" class="btn btn-success ">Añadir</button> </div> </form> </div> <div class="col-md-8 "> <h1 class="mt-3 display-3 ">Bolsa de horas</h1> <table class="table table-striped "> <thead> <tr> <th>Nombre cliente</th> <th>Horas contratadas</th> <th>Horas restantes</th> <th>Tipo empleado</th> <th>Importe</th> <th>Acciones</th> </tr> </thead> <tbody id="tabla"> </tbody> </table> </div> </div> </div> <script src="js/script.js"></script> </body> </html>
let estado = {} // Para guardar todos los componentes que me hacen falta window.onload = function () { // Guardo todos los accesos a los elementos html que necesito // Me olvido del html para el resto del código estado.tabla=document.getElementById("tabla"); estado.cliente=document.getElementById("cliente"); estado.horas=document.getElementById("horas"); estado.addPedido=document.getElementById("addPedido"); estado.tipoEmpleado=document.getElementsByClassName("tipoEmpleado"); estado.tipoSeleccionado="" estado.precios={"Junior":30,"Senior":60,"Master":80} asociarEventos("tipoEmpleado",clickEmpleado); estado.pedidos=[] estado.addPedido.addEventListener("click",addPedido); iniciar(); } function iniciar() { // Rcupero los datos del storage esto se hace solo una vez getStorageData(); pintarPedidos(); } function addPedido(){ // Recuperar los datos del formulario let horas=Number(estado.horas.value); let precio=estado.precios[estado.tipoSeleccionado] || 30; let pedido={ nombre:estado.cliente.value, horas:horas, tipoEmpleado:estado.tipoSeleccionado, // TODO: a ver que hago con esto restantes:horas, importe:horas*precio } // Añadir al pedido el objeto estado.pedidos.push(pedido); // volver a pintar los datos pintarPedidos(); } function consumir(){ let idpedido=this.dataset.idpedido; estado.pedidos[idpedido].restantes--; if (estado.pedidos[idpedido].restantes<=0){ estado.pedidos.splice(idpedido,1); } pintarPedidos(); } function clickEmpleado(){ for (let boton of estado.tipoEmpleado){ boton.classList.remove("active"); } this.classList.add("active"); estado.tipoSeleccionado=this.innerHTML } // Una capa intermedia entre la función pura y nuestro programa // Con el fin de que todo sea más escalable function pintarPedidos() { setStorageData(); pintarDatos(estado.pedidos, estado.tabla) } function pintarDatos(pedidos, destino) { lista = ""; let totalHoras=0; let totalImporte=0; let i=0; for (let pedido of pedidos) { lista += `<tr> <td>${pedido.nombre}</td> <td>${pedido.horas}</td> <td>${pedido.restantes}</td> <td>${pedido.tipoEmpleado}</td> <td>${pedido.importe}</td> <td> <button data-idpedido="${i}" type="button" class="btn btn-danger btn-sm consumir"> Consumir </button> </td></tr>`; i++ totalHoras+=pedido.restantes; totalImporte+=pedido.importe } lista += pedidos.length>0?`<tr><td></td><td>Horas</td> <td>${totalHoras}</td><td>Importe</td><td>${totalImporte}</td></tr>`:""; destino.innerHTML = lista; asociarEventos("consumir",consumir) } // Funciones de localStorage function getStorageData(){ let pedidos=localStorage.getItem("pedidos") || "[]"; pedidos=JSON.parse(pedidos); estado.pedidos=pedidos } function setStorageData(){ localStorage.setItem("pedidos",JSON.stringify(estado.pedidos)) } function asociarEventos(clase,funcion){ for (let boton of document.getElementsByClassName(clase)) { boton.addEventListener("click",funcion); } }
Más ejercicios listas
# funcion pivote de una lista de números nos divide la lista en 2 partes # primero los menores del número que pasemos y por otra los mayores # pivote([4,1,9,5,3,7],6)->([4,1,5,3],[9,7]) def pivote(lista, elemento): izq = [] der = [] for i in lista: if i < elemento: izq.append(i) elif i > elemento: der.append(i) return (izq, der) print(pivote([4, 1, 9, 6, 5, 3, 7], 6)) izq,der=pivote([4, 1, 9, 6, 5, 3, 7], 6) print(izq,der) # funcion ordenarLista a la que le pasamos una lista de palabras y nos la ordena por la longitud de las cadenas # ordenarLista(["bbb","a","ddddd","cccc"])->["a","bbb","cccc","ddddd"] def ordenarLista(lista): lista2=lista.copy() lista2.sort(key=len) return lista2 # funcion aplicarFuncion a la que le pasamos una lista de numeros y una función y nos devuelve la lista aplicando la función a cada uno de los elementos def doble(numero): return numero*2 def aplicarFuncion(lista,funcion): lista2 = [funcion(x) for x in lista] return lista2 print(aplicarFuncion([1,2,3,4],doble))
Ejercicios listas
# escribir una función recortarPalabras a la que le pasamos una lista de palabras # y una longitud y nos devuelve una lista con las palabras de esa lonitud o superior # recortarPalabras(["aa","bbb","cccc","dddddd"],4)->["cccc","dddddd"] # con comprensión de listas es muy fácil # escribir una función a la que le pasamos una lista de números y nos devuelve la mitad # de los números pares, los impares los ignora # mitadPares([1,2,5,8,10])->[1,4,5] # escribir una función a la que le pasamos dos listas y nos devuelve true si tienen # algún elemento en común y false en caso contrario # elementoComun([1,2,3],[4,5,6])->false # elementoComun([1,2,3],[4,5,6,3])->true # (es más fácil de lo que parece) # escribir una función a la que le pasamos una lista de números y nos devuelve una tupla # con la suma y la media de los números # estadistica([1,2,3])->(6,2)
Desempaquetar
tupla = (1, 2, 3) a, b, c = tupla # desempaquetando la tupla. A las variables se les asignan automáticamente los # valores de la tupla print(a, b, c) def extremos(*args): min = args[0] max = args[0] for n in args: if n < min: min = n if n > max: max = n return (min, max) # tupla = extremos(1, 5, 3, 7, 9, 0, -2) a, b = extremos(1, 5, 3, 7, 9, 0, -2) print(a, b) a, _, b = tupla # con el guión bajo ignoro elementos print(a, b) tupla=(1, 5, 3, 7, 9, 0, -2) a,*b,c=tupla # con el asterisco capturo un numero indeterminado de elementos print(a,b,c) a,*_,c=tupla # con el asterisco y guion bajo ignoro un numero indeterminado de elementos print(a,c)
Tuplas
# las tuplas son como las listas pero inmutables # se definen con paréntesis tupla = (1, 2, 3, 4, 5,6,7,8,9,10) print(tupla[0]) print(len(tupla)) for t in tupla: print(t) for i in range(len(tupla)): print (i,tupla[i]) # El mismo slicing que cadenas y listas print(tupla[2:4]) print(tupla[2:]) print(tupla[:4]) print(tupla[2:-2]) print(tupla[-7:-2]) print(tupla[0::2]) # El operador in que lo teníamos en las cadenas también lo tenemos en tuplas y listas if 8 in tupla: print("El 8 está en la tupla") # sumar tuplas otra=(1,2,3) suma=tupla+otra print(tupla,otra,suma) lista=list(suma) print(lista)
Ordenación de listas
# sumar listas para crear listas nuevas con los elementos de las listas sumados lista1 = [1, 2, 3] lista2 = [4, 5, 6] lista3 = lista1 + lista2 print(lista1, lista2, lista3) # añadir a una lista existente otra lista lista1.extend(lista2) print(lista1, lista2, lista3) lista4 = lista2 + lista1 print(lista4) lista4.sort() print(lista4) lista4.sort(reverse=True) print(lista4) alumnos = ["Ana", "Eva", "pep", "Iu", "juan", "Rosa", "Iu", "Iu"] alumnos.sort() print(alumnos) # usando key lo que le digo es que antes de ordenar aplique esa función alumnos.sort(key=str.lower) print(alumnos) def valorAbsoluto(numero): if numero<0: numero=-numero return numero valores=[1,-3,6,-2,-8,3,-4] valores.sort(key=valorAbsoluto) print(valores) def nombreCompleto(tratamiento,nombre,apellido): return tratamiento+" "+nombre+" "+apellido print(nombreCompleto("Sr.","Pepito","Pérez")) print(nombreCompleto(nombre="Ana",tratamiento="Excelentísima",apellido="Pi"))
Comprensión de listas en Python: ejemplos
# eliminar elementos nums = ["Ana", "Eva", "Pep", "Iu", "Juan", "Rosa", "Iu", "Iu"] print(nums) nums.pop(2) # elimino el que está en la posición 2 print(nums) nums.remove("Iu") # Busca 'Iu' y lo elimina print(nums) print(nums) for numero in nums: print(numero) # for x in lista es el núcleo de la comprensión de listas # la parte izquierda es la transformación del elemento nueva = ["@" + elemento for elemento in nums] print(nueva) notas = [1, 2, 3, 4, 5, 7, 8, 9] transformada = [nota * 2 for nota in notas] print(transformada) trans2 = [nota for nota in notas] print(trans2) trans3 = [7 for nota in notas] print(trans3) trans2 = [nota for nota in notas if nota % 2 == 0] print(trans2) nueva = [elemento for elemento in nums if len(elemento) > 3] print(nueva) precios = [10, 20, 15, 70, 32, 40] pvp = [precio * 1.21 for precio in precios if precio >= 20] print(pvp) edad = 16 # Operador ternario print("Mayor de edad" if edad >= 18 else "Menor de edad") aprobar = [5 if nota < 5 else nota for nota in notas] print(aprobar) def cuadrado(num): return num ** 2 cuad = [cuadrado(num) for num in notas] print(cuad)