Conjuntos: operaciones y usos
Introducción
Los conjuntos en Python son colecciones desordenadas de elementos únicos. Comparten características con los conjuntos matemáticos, lo que los hace especialmente útiles para operaciones como la unión, intersección o diferencia. A diferencia de las listas o tuplas, los conjuntos no permiten elementos duplicados y no mantienen un orden específico, lo que los convierte en estructuras muy eficientes para ciertas tareas. En este artículo, aprenderemos qué son los conjuntos, cómo trabajar con ellos y qué operaciones podemos realizar.
Creación de conjuntos
Existen dos formas principales de crear conjuntos en Python:
# Usando llaves
colores = {"rojo", "verde", "azul"}
print(colores) # Puede mostrar {'verde', 'rojo', 'azul'} (orden no garantizado)
# Usando la función set()
numeros = set([1, 2, 3, 2, 1]) # Los duplicados se eliminan automáticamente
print(numeros) # Muestra {1, 2, 3}
# Conjunto vacío (¡importante! {} crea un diccionario vacío, no un conjunto)
conjunto_vacio = set()
print(conjunto_vacio) # Muestra set()
Es importante tener en cuenta que no podemos crear un conjunto vacío utilizando {}
, ya que esto crea un diccionario vacío. Debemos usar set()
en su lugar.
Características de los conjuntos
Los conjuntos tienen varias características distintivas:
-
Elementos únicos: No permiten duplicados
numeros = {1, 2, 3, 2, 1} print(numeros) # Muestra {1, 2, 3} - los duplicados se eliminan
-
Desordenados: No tienen un orden específico
conjunto = {3, 1, 2} # El orden de impresión puede variar print(conjunto) # Podría mostrar {1, 2, 3} o cualquier otra permutación
-
Elementos inmutables: Solo pueden contener elementos inmutables como números, cadenas y tuplas (no listas o diccionarios)
# Válido - todos los elementos son inmutables conjunto_valido = {1, "hola", (1, 2)} # Inválido - las listas son mutables # conjunto_invalido = {1, [2, 3]} # Esto provocaría un error TypeError
Operaciones básicas con conjuntos
Añadir y eliminar elementos
frutas = {"manzana", "naranja"}
# Añadir un elemento
frutas.add("plátano")
print(frutas) # {'manzana', 'naranja', 'plátano'}
# Eliminar un elemento (provoca error si no existe)
frutas.remove("naranja")
print(frutas) # {'manzana', 'plátano'}
# Eliminar un elemento (no provoca error si no existe)
frutas.discard("pera") # No hace nada porque "pera" no está en el conjunto
print(frutas) # {'manzana', 'plátano'}
# Extraer y eliminar un elemento aleatorio
elemento = frutas.pop()
print(elemento) # Podría ser 'manzana' o 'plátano'
print(frutas) # El conjunto sin el elemento extraído
# Eliminar todos los elementos
frutas.clear()
print(frutas) # set()
Comprobación de pertenencia
animales = {"perro", "gato", "pez"}
# Comprobar si un elemento está en el conjunto
print("gato" in animales) # True
print("león" in animales) # False
Operaciones matemáticas con conjuntos
Las operaciones matemáticas son una de las características más potentes de los conjuntos en Python:
Unión (elementos que están en cualquiera de los conjuntos)
grupo_a = {1, 2, 3}
grupo_b = {3, 4, 5}
# Usando el operador |
union = grupo_a | grupo_b
print(union) # {1, 2, 3, 4, 5}
# Usando el método union()
union = grupo_a.union(grupo_b)
print(union) # {1, 2, 3, 4, 5}
Intersección (elementos comunes a ambos conjuntos)
grupo_a = {1, 2, 3}
grupo_b = {3, 4, 5}
# Usando el operador &
interseccion = grupo_a & grupo_b
print(interseccion) # {3}
# Usando el método intersection()
interseccion = grupo_a.intersection(grupo_b)
print(interseccion) # {3}
Diferencia (elementos en el primer conjunto pero no en el segundo)
grupo_a = {1, 2, 3}
grupo_b = {3, 4, 5}
# Usando el operador -
diferencia = grupo_a - grupo_b
print(diferencia) # {1, 2}
# Usando el método difference()
diferencia = grupo_a.difference(grupo_b)
print(diferencia) # {1, 2}
Diferencia simétrica (elementos que están en uno u otro conjunto, pero no en ambos)
grupo_a = {1, 2, 3}
grupo_b = {3, 4, 5}
# Usando el operador ^
dif_simetrica = grupo_a ^ grupo_b
print(dif_simetrica) # {1, 2, 4, 5}
# Usando el método symmetric_difference()
dif_simetrica = grupo_a.symmetric_difference(grupo_b)
print(dif_simetrica) # {1, 2, 4, 5}
Verificación de subconjuntos y superconjuntos
numeros = {1, 2, 3, 4, 5}
pares = {2, 4}
impares = {1, 3, 5}
# Comprobar si es un subconjunto (todos los elementos de pares están en numeros)
print(pares.issubset(numeros)) # True
print(pares <= numeros) # True (operador de subconjunto)
# Comprobar si es un superconjunto (todos los elementos de pares están en numeros)
print(numeros.issuperset(pares)) # True
print(numeros >= pares) # True (operador de superconjunto)
# Comprobar si son disjuntos (no tienen elementos en común)
print(pares.isdisjoint(impares)) # True (no comparten elementos)
Casos de uso prácticos
Los conjuntos son especialmente útiles en ciertos escenarios:
Eliminación de duplicados
# Convertir una lista con duplicados a un conjunto elimina los duplicados
numeros_duplicados = [1, 2, 2, 3, 4, 3, 5]
numeros_unicos = set(numeros_duplicados)
print(numeros_unicos) # {1, 2, 3, 4, 5}
# Si necesitamos volver a una lista, podemos convertir de nuevo
lista_sin_duplicados = list(numeros_unicos)
print(lista_sin_duplicados) # [1, 2, 3, 4, 5] (aunque el orden puede variar)
Encontrar elementos comunes o únicos entre colecciones
alumnos_matematicas = {"Ana", "Pedro", "Luis", "María"}
alumnos_fisica = {"Pedro", "María", "Carmen", "Jorge"}
# Estudiantes que toman ambas asignaturas
ambas_asignaturas = alumnos_matematicas & alumnos_fisica
print(ambas_asignaturas) # {'Pedro', 'María'}
# Estudiantes que solo toman matemáticas
solo_matematicas = alumnos_matematicas - alumnos_fisica
print(solo_matematicas) # {'Ana', 'Luis'}
# Todos los estudiantes únicos
todos_los_estudiantes = alumnos_matematicas | alumnos_fisica
print(todos_los_estudiantes) # {'Ana', 'Pedro', 'Luis', 'María', 'Carmen', 'Jorge'}
Comprobación de pertenencia eficiente
Los conjuntos son mucho más eficientes que las listas para comprobar si un elemento está presente:
# Para listas largas, buscar en un conjunto es mucho más rápido
numeros_grandes = list(range(10000))
conjunto_numeros = set(numeros_grandes)
# Verificación de pertenencia (más eficiente en conjuntos que en listas)
numero_buscado = 9999
# Ambos devuelven True, pero el conjunto es mucho más rápido
print(numero_buscado in numeros_grandes) # Operación lenta en listas largas
print(numero_buscado in conjunto_numeros) # Operación rápida incluso con conjuntos grandes
Comprensión de conjuntos
Al igual que con las listas, podemos usar comprensiones para crear conjuntos de manera concisa:
# Crear un conjunto de cuadrados de números del 0 al 9
cuadrados = {x**2 for x in range(10)}
print(cuadrados) # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
# Crear un conjunto de vocales de una cadena
texto = "programacion en python"
vocales = {letra for letra in texto if letra in "aeiou"}
print(vocales) # {'a', 'e', 'i', 'o', 'u'}
Resumen
Los conjuntos son estructuras de datos versátiles en Python que nos permiten trabajar con colecciones de elementos únicos y aplicar operaciones matemáticas de conjuntos. Son especialmente útiles cuando necesitamos eliminar duplicados, realizar operaciones de unión, intersección o diferencia, o comprobar la pertenencia de elementos de manera eficiente. Aunque tienen limitaciones como no mantener un orden específico o no poder contener elementos mutables, los conjuntos son una herramienta poderosa que complementa a las listas, tuplas y diccionarios en Python.
En el siguiente artículo exploraremos los métodos comunes de las diferentes estructuras de datos en Python, lo que nos permitirá aprovechar al máximo estas potentes herramientas.