Tuplas y conjuntos
Ya conoces las listas. Python tiene dos tipos más de colecciones que resuelven problemas que las listas no pueden. Las tuplas guardan un grupo fijo de valores que nunca cambiarán. Los conjuntos guardan solo valores únicos y te permiten comprobar la pertenencia instantáneamente, sin importar lo grande que sea la colección.
Tuplas
Una tupla es un grupo ordenado de valores que no puede cambiarse después de crearlo. Los paréntesis definen una tupla, pero son opcionales. Lo que realmente la convierte en tupla es la coma. Una tupla de un solo elemento requiere una coma final.
point = (10, 20)
rgb = (255, 128, 0)
dimensions = (1920, 1080)
single = (42,) # se requiere una coma final para una tupla de un solo elemento
also_tuple = 42, 99 # los paréntesis son opcionales; la coma la convierte en tuplaEl acceso por índice funciona exactamente igual que en una lista. Intentar cambiar un elemento lanza un TypeError:
point = (10, 20)
point[0] # 10
point[1] # 20
point[-1] # 20
point[0] = 99 # TypeError: 'tuple' object does not support item assignmentCuándo usar una tupla
Usa una tupla cuando tengas un grupo pequeño de valores relacionados que vayan juntos y no vayan a cambiar. Coordenadas (x, y), un color (r, g, b), un par nombre-puntuación ("Sofía", 87). La estructura fija le indica a cualquier persona que lea el código que este grupo se trata como una sola unidad.
locations = {}
locations[(40, -74)] = "Ciudad de México" # tupla como clave de diccionario, funciona
locations[[40, -74]] = "Ciudad de México" # lista como clave de diccionario, TypeErrorDesempaquetado
El desempaquetado extrae valores de una tupla y asigna cada uno a su propio nombre en una sola línea. La cantidad de nombres debe coincidir con la cantidad de valores. Usa * para capturar los elementos restantes en una lista.
point = (10, 20)
x, y = point
print(x) # 10
print(y) # 20
first, *rest = [1, 2, 3, 4, 5]
# first = 1, rest = [2, 3, 4, 5]
head, *middle, tail = [1, 2, 3, 4, 5]
# head = 1, middle = [2, 3, 4], tail = 5Tuplas con nombre
Una tupla con nombre es una tupla donde cada posición tiene un nombre. En lugar de recordar que point[0] es la coordenada x, escribes point.x. Los valores siguen siendo inmutables; solo obtienes nombres de atributos legibles en vez de posiciones numéricas.
Importación de named tuple
namedtuple está en la biblioteca estándar de Python, pero hay que importarla. La línea from collections import namedtuple es la primera importación de este curso. Las importaciones se cubren a fondo en el capítulo Módulos.
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
Player = namedtuple("Player", ["name", "score", "level"])
p = Point(10, 20)
p.x # 10
p.y # 20
sofia = Player("Sofía", 87, 5)
sofia.name # "Sofía"
sofia.score # 87Conjuntos
Un conjunto es una colección de valores únicos sin un orden garantizado. Añadir el mismo valor dos veces no hace nada: un conjunto solo conserva una copia de cada elemento. Usa llaves para un conjunto con elementos, o set() para crear un conjunto vacío.
tags = {"python", "beginner", "tutorial"}
numbers = {1, 2, 3, 4, 5}
empty = set() # NO {} (eso es un diccionario vacío)Añadir el mismo valor dos veces no cambia el conjunto:
tags.add("python") # tags no cambia, "python" ya está en élCuándo usar un conjunto
Los conjuntos son la herramienta adecuada para tres cosas: eliminar duplicados de una lista, comprobar rápidamente si algo está en una colección grande y comparar dos grupos para encontrar lo que comparten o en qué difieren.
# Eliminar duplicados de una lista
raw = ["gato", "perro", "gato", "pájaro", "perro", "gato"]
unique = list(set(raw)) # ["gato", "perro", "pájaro"] (orden no garantizado)# Comprobación rápida de pertenencia
valid_codes = {"USD", "EUR", "GBP", "JPY"}
code = "EUR"
if code in valid_codes: # búsqueda instantánea, incluso con miles de códigos
print("Válido")Operaciones con conjuntos
Los conjuntos admiten las mismas operaciones que aprendiste en matemáticas: unión (todo lo que está en cualquiera de los conjuntos), intersección (solo lo que ambos comparten) y diferencia (lo que uno tiene y el otro no). Python usa símbolos de operador para esto, y cada uno tiene un método equivalente.
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
a | b # {1, 2, 3, 4, 5, 6} (unión: todo en cualquiera)
a & b # {3, 4} (intersección: solo en ambos)
a - b # {1, 2} (diferencia: en a pero no en b)
b - a # {5, 6} (diferencia en el otro sentido)
a ^ b # {1, 2, 5, 6} (diferencia simétrica: en uno pero no en ambos)Estos también tienen formas de método: .union(), .intersection(), .difference(), .symmetric_difference().
Modificación de conjuntos
Los conjuntos son mutables. .add() añade un elemento. .update() añade varios a la vez desde cualquier lista u otro iterable. .remove() elimina un elemento pero lanza un error si no está. .discard() elimina silenciosamente si el elemento existe y no hace nada si no existe.
tags = {"python", "beginner"}
tags.add("tutorial") # añadir un elemento
tags.update(["web", "api"]) # añadir múltiples elementos desde cualquier iterable
tags.remove("beginner") # eliminar, lanza KeyError si no se encuentra
tags.discard("missing") # eliminar, sin error si no se encuentra
tags.pop() # eliminar y devolver un elemento arbitrario
tags.clear() # eliminar todoUsa .discard() cuando no estés seguro de si el elemento existe.
Conjuntos congelados
Un conjunto congelado es un conjunto que no puedes modificar después de crearlo. La razón principal para usarlo: los conjuntos congelados son hashables, por lo que se pueden usar como claves de diccionario o almacenarse dentro de otros conjuntos.
valid_statuses = frozenset({"active", "paused", "deleted"})
valid_statuses.add("archived") # AttributeError, frozenset es inmutableElegir la colección adecuada
Cuatro tipos, cada uno con un rol claro. Pregúntate qué necesitas hacer con los datos y la elección correcta normalmente se vuelve obvia.
| list | tuple | set | dict | |
|---|---|---|---|---|
| Ordenado | Sí | Sí | No | Sí (orden de inserción) |
| Mutable | Sí | No | Sí | Sí |
| Duplicados | Sí | Sí | No | No (claves) |
| Acceso por | Índice | Índice | n/a | Clave |
| Usar cuando | Secuencia ordenada y modificable | Registro fijo | Valores únicos, pertenencia rápida | Búsqueda clave-valor |
Una regla rápida de decisión:
- ¿Necesitas buscar algo por nombre? → dict
- ¿Necesitas una colección ordenada que vas a modificar? → list
- ¿Tienes un grupo fijo de valores relacionados? → tuple
- ¿Necesitas valores únicos o pruebas de pertenencia rápidas? → set
En la práctica
Usando tuplas para almacenar registros fijos y un conjunto para llevar un control de valores únicos:
home = (51.5074, -0.1278) # latitud, longitud
office = (51.5155, -0.0922)
home_lat, home_lon = home
print(f"Casa: {home_lat}, {home_lon}")
# Llevar un control de visitantes únicos con un conjunto
visitors = set()
visitors.add("sofia")
visitors.add("mateo")
visitors.add("sofia") # ya está en el conjunto, se ignora silenciosamente
visitors.add("camila")
print(f"Visitantes únicos: {len(visitors)}")
print(f"sofia visitó: {'sofia' in visitors}")
print(f"diego visitó: {'diego' in visitors}")
