jueves, 13 de junio de 2024

Lenguajes. Python.

Tuplas.

Manejo básico

Después de las listas, las tuplas son el [segundo tipo de colecciones de datos] del lenguaje Python. En esta entrada, siguiendo [el modelo de la anterior], recordaremos sus características y aprenderemos a manejarlas.

      

La palabra tupla no existe en español, aunque sí en el lenguaje matemático, derivada de la generalización de la secuencia dupla, tripla.. n-tupla..., esto es, como lista ordenada finita de elementos.

En informática, una tupla es una lista inmutable y ese es el significado que tiene también en Python. En consecuencia, una tupla no es más que una lista cerrada, que no se puede modificar una vez creada, lo que equivale a decir que es un tipo específico de lista. Mientras que una lista se pueden modificar (por lo que podríamos redefinirla como listas abierta o mutable), una tupla (o lista cerrada o inmutable) no se pueden modificar.

En Python para diferenciar lista de tupla se modifica su sintaxis básica: mientras la lista se identifica por el uso de corchetes, en la tupla se emplea el paréntesis...

miLista = ["perro","gato","lobo"]
miTupla = ("perro","gato","lobo")

... pero en ambas los datos se separan por comas y es el valor de posición (el índice) que ocupan en su seno lo que permite identificarlos (1):

print(miLista[1]) -> gato 
print(miTupla[1]) -> gato

Al ser las tuplas inmutables las podemos considerar equivalentes a las constantes frente a las variables (que serían las listas), por lo que su utilidad es equivalente a la de aquellas. Los tuplas no admiten ciertas operaciones que sí son posibles en las listas, como añadir elementos, modificarlos o borrarlos, por lo que no cambian ni de estructura ni de contenidos a lo largo de todo el algoritmo.

No obstante, una tupla no deja de ser una colección de datos que puede contener distintos tipos de elementos. Del mismo modo que las listas pueden contener, además de datos de diferentes tipos, otras listas y también tuplas, las tuplas pueden tener la misma composición, incluyendo listas. Y al ser las listas elementos mutables, una tupla que contenga una lista podrá ser modificable, no en cuanto tupla, pero sí ese elemento de la tupla definido como lista. Detengámonos un momento a analizar estas cuestiones.

miTupla = ("casa","mesa")
print(miTupla) -> ('casa', 'mesa')
miTupla[0]="silla"

        -> Devuelve error 

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    miTupla[0]="silla"
TypeError: 'tuple' object does not support item assignment

Aquí hemos definido una tupla de dos elementos. Si queremos modificar uno de ellos mediante asignación (como hacemos en una lista) el resultado es un mensaje de error (en rojo) que nos informa que el objeto tupla no soporta la asignación de ítem, o sea, que no se puede modificar. Tampoco podríamos hacer otros cambios que sí son posibles en las listas, como añadir un nuevo elemento, borrarlo...
 
miLista=[1,2,3]
miTupla=("casa","mesa",miLista)
print(miTupla) -> ('casa', 'mesa', [1, 2, 3])
miTupla[0]="armario" -> Devuelve error
Traceback (most recent call last):File "<pyshell#12>", line 1, in <module> miTupla[0]="armario". TypeError: 'tuple' object does not support item assignment 
print(miTupla[2][0]) -> 1
miTupla[2][0]=0
print(miTupla) -> ('casa', 'mesa', [0, 2, 3])

En este segundo ejemplo, la tupla contiene tres elementos, siendo el tercero [2], una lista definida con anterioridad (miLista). Podemos comprobar de nuevo que si queremos modificar el elemento [0] nos devuelve error, pero si lo que deseamos es modificar el elemento [2][0] (tercer elemento de la tupla  y primero de esa lista), es perfectamente posible hacerlo: la orden miTupla[2][0]=0 no devuelve error y se ejecuta correctamente (print(miTupla) -> ('casa', 'mesa', [0, 2, 3])

Para finalizar esta entrada, advirtiendo antes que aun quedan muchas cosas por aprender de las listas y de las tuplas, vamos a ver una aplicación práctica combinando listas y tuplas y bucles o ciclos. 

En realidad este ejercicio se puede considerar complementario tanto de esta entrada como de la anterior, ya que desarrolla un tema que en aquella quedó indicado pero no resuelto: dije entonces que podíamos crear listas sin elementos (sin contenido), pero no dije qué utilidad podrían tener tales listas. Ahora veremos una de ellas. Utilizar una tupla como marco de referencia, concreta también una de sus utilidades (2): respetar la estructura básica de una formulación asimilable a base de datos.

El [algoritmo resultante queda aquí] a tu disposición para que lo estudies. La idea es que crees tú algún otro semejante y compares tu solución con la mía, que ya advierto no es perfecta, puesto que el resultado final...

Ejemplo para dos alumnos hipotéticos

(['Carmela', 'Alejandro'], ['Álvarez López', 'Ramírez Suárez'], ['1', '1', '1', '0', '1', '0', '1', '1', '0', '0', '1', '1', '1', '0']) 

... no es del todo satisfactorio: mi idea era obtener el siguientes resultado para el tercer componente de la tupla (dos elementos lista en lugar de un único elemento)

[['1', '1', '1', '0', '1', '0', '1'],[ '1', '0', '0', '1', '1', '1', '0']]

... pero no me ha sido posible... por el momento.

Aunque este error relativo respecto al objetivo es importante y habrá que estudiar cómo remediarlo, sí hay algunos logros de interés que te quiero comentar brevemente:
  • En la entrada sobre listas decía que la expresión  lstPalabras = lstPalabras + ["mesita"] permitía añadir un nuevo elemento a la lista, y es correcto, pero para añadir un elemento en otros contextos de mayor complejidad necesitamos emplear una función (append()), como puedes observar en el algoritmo de ejemplo:
vNombre=input("Nombre: ")
    lstNombres.append(vNombre)

  • Podemos declarar listas vacías y cumplimentarlas mediante un bucle en función de una decisión previa: en mi ejemplo, el número de alumnos del listado, que sirve para establecer el número de ciclos o iteraciones que realiza el bucle for
vNumAl = int(input("Dime el número de alumnos y alumnas del grupo: "))
(...)
for i in range(vNumAl):

  • Podemos anidar un bucle for dentro de otro bucle, generando estructuras complejas. En mi ejemplo el bucle principal contiene un bucle secundario. Las iteraciones del primero vienen dadas interactivamente, pero las del segundo vienen determinadas por un valor implícito: el número de ítem de la prueba: for u in range(7):
  • Aunque lo que manejamos son listas (y por eso las podemos modificar), la estructura principal es una tupla, ya que queremos que su estructura básica (la del "registro") sea invariable (3).


NOTAS

(1) Como curiosidad, obsérvese que en ambos casos usamos corchetes para contener el índice.
(2) Precisamente aquella en la que su rigidez se puede considerar una virtud.
(3) Precisamente la limitación de este algoritmo es no haber conseguido reproducir la forma esperada en un diseño de base de datos: ser resultante de la unión o consulta de dos tablas: datos personales y resultados. Si obtengo un resultado mejor, lo publicaré.

No hay comentarios:

Publicar un comentario

Comenta esta entrada