Una tupla es una colección inmutable de elementos en secuencia.
Como la mayoría de las colecciones (consulta los tipos integrados list, dict y set), tuples pueden contener cualquier tipo de datos (o varios), incluidos otros tuples.
Los elementos de una tupla se pueden recorrer con la construcción for item in <tuple>.
Si necesitas tanto el índice como el valor de cada elemento, puedes usar for index, item in enumerate(<tuple>).
Como en cualquier secuencia, se puede acceder a los elementos de tuples mediante la notación de corchetes, usando un 0-based index desde la izquierda o un -1-based index desde la derecha.
Las tuplas se pueden copiar total o parcialmente mediante la notación de rebanada o <tuple>.copy(), y admiten todas las operaciones comunes de secuencia.
Al ser inmutables, tuples no admiten las operaciones de secuencia mutables.
Las tuplas ocupan muy poco espacio en memoria en comparación con otros tipos de colección y tienen un tiempo de acceso constante (O(1)) cuando se usa un índice.
Sin embargo, no se pueden redimensionar, ordenar ni modificar una vez creadas, por lo que son menos flexibles cuando necesitas cambios o actualizaciones frecuentes en los datos.
Si necesitas actualizaciones o ampliaciones frecuentes, puede que list, collections.deque o array.array sean una estructura de datos mejor.
Las tuplas se pueden crear de varias formas, usando el constructor de la clase tuple o la declaración (<element_1>, <element_2>) (literal de tuple).
tuple() vacío o con un iterable:>>> no_elements = tuple()
()
# The constructor *requires* an iterable, so single elements must be passed in a list or another tuple.
>>> one_element = tuple([16])
(16,)
Los strings son iterables, así que usar un solo str como argumento del constructor tuple() puede dar resultados sorprendentes:
# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')
Otros iterables también añaden sus elementos uno a uno:
>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)
>>> multiple_elements_set = tuple({2, 3, 5, 7, 11})
(2,3,5,7,11)
La iteración predeterminada de dict recorre las claves.
Para incluir tanto las claves como los valores en una tupla creada a partir de un diccionario, usa <dict>.items(),
que devuelve un iterador de tuples con forma (key, value).
>>> source_data = {"fish": "gold", "monkey": "brown"}
>>> multiple_elements_dict_1 = tuple(source_data)
('fish', 'monkey')
>>> multiple_elements_dict_2 = tuple(source_data.items())
(('fish', 'gold'), ('monkey', 'brown'))
Como el constructor tuple() solo acepta iterables (o nada) como argumentos, es mucho más fácil crear una tupla de un solo elemento con el método literal.
>>> no_elements = ()
()
>>> one_element = ("Guava",)
("Guava",)
Ten en cuenta que, por lo general, los paréntesis no son necesarios para crear un literal de tuple, solo las comas.
Sin embargo, usar (<element_1>, <element_2>) se considera más legible en la mayoría de los casos.
Los paréntesis también son necesarios en casos de ambigüedad, como una tupla vacía o de un solo elemento, o cuando una función recibe una tupla como argumento.
>>> elements_separated_with_commas = "Parrot", "Bird", 334782
("Parrot", "Bird", 334782)
>>> elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60)
("Triangle", 60, 60, 60)
Otras estructuras de datos se pueden incluir como elementos de tuple, incluidas otras tuples.
>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
>>> nested_data_structures_1 = (["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
(["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
Las tuplas se pueden concatenar con el operador más +, que desempaqueta cada tuple y crea una nueva tuple combinada.
>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby")
("George", 5, "cat", "Tabby")
#likewise, using the multiplication operator * is the equivalent of using + n times
>>> first_group = ("cat", "dog", "elephant")
>>> multiplied_group = first_group * 3
('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant')
Se puede acceder a los elementos de las tuplas (al igual que en los otros tipos de secuencia str y list) mediante la notación de corchetes.
Los índices pueden ir de left --> right (empezando en cero) o de right --> left (empezando en -1).
Las tuplas también se pueden copiar total o parcialmente mediante la notación de rebanada o usando <tuple>.copy().
>>> student_info = ("Alyssa", "grade 3", "female", 8)
#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa
>>> student_name = student_info[-4]
Alyssa
#age is at index 3 or index -1
>>> student_age_1 = student_info[3]
8
>>> student_age_2 = student_info[-1]
8
Los elementos de las tuplas se pueden recorrer en un bucle con la sintaxis for item in <tuple>.
Si necesitas tanto los índices como los valores, puedes usar for index, item in enumerate(<tuple>).
>>> student_info = ("Alyssa", "grade 3", "female", 8)
>>> for item in student_info:
... print(item)
...
Alyssa
grade 3
female
8
>>> for index, item in enumerate(student_info):
... print("Index is: " + str(index) + ", value is: " + str(item) + ".")
...
Index is: 0, value is: Alyssa.
Index is: 1, value is: grade 3.
Index is: 2, value is: female.
Index is: 3, value is: 8.
A menudo se usan tuplas como registros que contienen datos organizativa o conceptualmente homogéneos y se tratan como una única unidad de información, aunque los elementos individuales sean de tipos de datos heterogéneos.
>>> student_info = ("Alyssa", "grade 3", "female", 8)
Las tuplas también se usan cuando se necesitan secuencias de datos homogéneas e inmutables para la hashability, el almacenamiento en un set o la creación de claves en un diccionario.
Ten en cuenta que, aunque tuples son inmutables en la mayoría de los casos, como pueden contener cualquier estructura de datos u objeto, pueden volverse mutables si alguno de sus elementos es de un tipo mutable.
Usar un tipo de datos mutable dentro de una tuple hará que la tuple que lo contiene no se pueda usar como hash.
>>> cmyk_color_map = {
(.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292),
(0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01),
(.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E),
(0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C)
}
>>> unique_rgb_colors = {
(59, 178, 146),
(247, 127, 1),
(89, 16, 142),
(140, 0, 76),
(76, 0, 140)
}
>>> teal_700 = hash((59, 178, 146))
>>> teal_700 = hash(("Pantone 228", [(140, 0, 76), 0x8C004C]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
A menudo se usan tuplas como registros, pero solo se puede acceder a los datos que contienen mediante posición o índice.
La clase namedtuple() del módulo collections amplía la funcionalidad básica de las tuplas para permitir el acceso a los elementos por nombre.
Además, puedes adaptar una dataclass para ofrecer una funcionalidad similar de atributos con nombre, con sus ventajas e inconvenientes.