Conjuntos y algoritmos aplicados
Presentación
1. Definición de un conjunto
Un conjunto es una colección no ordenada de objetos únicos. No existe, por tanto, una relación de orden y resulta imposible encontrar dos elementos idénticos. Se trata, simple y llanamente, de un conjunto, en el sentido matemático del término.
Un conjunto se diferencia de una secuencia (lista o n-tupla) en que su uso es radicalmente distinto, mientras que las diferencias entre una lista y una n-tupla son de orden semántico y técnico.
Existen dos tipos de conjuntos, los conjuntos modificables (set) y los conjuntos no modificables (frozenset). La diferencia a nivel técnico es exactamente del mismo tipo que entre las listas y las n-tuplas.
Por el contrario, a nivel semántico, no existen diferencias entre un set y un frozenset -mientras que sí las hay entre una lista y una n-tupla-, dado que los dos se utilizan para representar el mismo tipo de datos, con el mismo significado.
Los puentes que hemos visto entre las n-tuplas, las listas y los iteradores funcionan también con los conjuntos. Es posible construir uno a partir de una lista, una tupla u otras secuencias:
>>> set([1, 2, 3])
{1, 2, 3}
Se comprueba, por otra parte, en la respuesta de la consola la nueva representación de un conjunto:
>>> {1, 2, 3}
{1, 2, 3}
No debe confundirse con un diccionario:
>>> {1:1, 2:2, 3:3}
{1: 1, 2: 2, 3: 3}
La representación...
Operaciones sobre conjuntos
1. Operadores para un conjunto a partir de otros dos
Conviene recordar la característica principal de un conjunto: no existen duplicados:
>>> s1 = {1, 2, 3, 3}
>>> s1
{1, 2, 3}
De este modo, es posible:
-
saber si un elemento se encuentra en el conjunto (__contains__):
>>> 3 in s1
True
-
conocer los elementos que se encuentran en s1, pero no en s2 (__sub__):
>>> s2 = {5, 4, 3}
>>> s1 - s2
{1, 2}
-
conocer los elementos presentes en s1 o en s2 (__or__), el «o» u «o inclusivo» lógico. Se trata de una unión en el sentido matemático:
>>> s1 | s2
{1, 2, 3, 4, 5}
-
conocer los elementos presentes al mismo tiempo en s1 y s2, la intersección de s1 y s2 o el «y» lógico (__and__):
>>> s1 & s2
{3}
-
conocer los elementos en s1 o s2, pero que no estén en ambos, el «o exclusivo» (__xor__):
>>> s1 ^ s2
{1, 2, 4, 5}
Una suma podría entenderse como en matemáticas, es decir, los objetos del primer conjunto se agregan a los objetos del segundo conjunto, salvo los objetos que pertenecen a la intersección de ambos conjuntos, puesto que no se permiten duplicados.
Dado que el conjunto es, por naturaleza, un conjunto, la suma realiza, en este caso, la misma acción que la unión, puesto que los duplicados se eliminan automáticamente. Podríamos agregar:
>>> class myset(set):
... __add__ = set.__or__
...
>>> a, b = myset({1, 2, 3}), myset({5, 4, 3})
>>> a+b
{1, 2, 3, 4, 5}
Haciendo esto aparece una ambigüedad, pues se proporcionan dos métodos con nombres diferentes para realizar la misma acción, lo cual resulta contrario a la filosofía de Python. Además, la semántica es importante, y debería estar orientada a conjuntos.
2. Operadores para modificar un conjunto a partir de otro
Es sencillo crear un conjunto a partir de otros dos y, a continuación, asignar el resultado a una variable. No obstante, eso puede escribirse de manera más sencilla mediante operadores...
Métodos de modificación de un conjunto
1. Agregar un elemento
Estos métodos están disponibles únicamente para conjuntos modificables de tipo set, y no para frozenset. El primero de ellos es add:
>>> s={1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(1)
>>> s
{1, 2, 3, 4}
Si el valor está presente en el conjunto, entonces no se modifica (agregar un elemento ya presente no supone un error).
Agregar un elemento es equivalente a realizar la unión con un conjunto que contenga, únicamente, dicho elemento:
>>> s|={5}
>>> s
{1, 2, 3, 4, 5}
2. Eliminar un elemento
Existen dos formas de eliminar un elemento de un conjunto. En primer lugar, el método remove, que se llama igual que para una lista pero recibe un único argumento, dado que no hay más que una única ocurrencia de cada objeto:
>>> s.remove(5)
Si el valor que se pide eliminar no se encuentra en el conjunto, se produce una excepción (el comportamiento es similar al de una lista, aunque el tipo de excepción es diferente):
>>> s.remove(8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 8
>>> [].remove(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
Otro medio de eliminar un elemento consiste en utilizar el método discard, que no produce ninguna excepción. Se obtiene el mismo resultado que con -=:
>>> s.discard(4)
>>> s.discard(8)
>>> s
{1, 2, 3}
>>> s-={3}
>>> s
{1, 2}
Ambos métodos responden a necesidades diferentes.
3. Vaciar un conjunto
Como todos los contenedores de objetos modificables, el conjunto posee un método clear que permite eliminar todos los valores del conjunto:
>>> s.clear()
>>> s
set()
4. Duplicar un elemento
El operador de asignación permite implementar la relación entre el nombre de una variable y un valor, aunque...