Python: Conjuntos (set)

Un conjunto (objeto set) es una colección desordenada de distintos objetos. Usos comunes incluyen pruebas de si es o no miembro del conjunto, eliminación de duplicados y cálculo de operaciones matemáticas como intersección (and), unión (or), diferencia y diferencia simétrica (xor). Para otros contenedores es mejor usar diccionarios, listas y tuple

.

Al igual que otras colecciones, los conjuntos (sets) admiten x in set, len(set) y for x in set. Al ser una colección desordenada, los conjuntos no registran la posición del elemento ni el orden de inserción. En consecuencia, los conjuntos no admiten indexación, división u otro comportamiento similar a una secuencia.

Para crear un conjunto vacío NO podemos usar conjunto = {} ya que esto crea un diccionario, para ello debemos usar conjunto.set().

Lo que hace es devolver un conjunto nuevo con todos los elementos únicos de todos los conjuntos

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.union(ips2)
Out[4]: {'172.16.20.33', '192.168.1.1', '3.3.3.3', '6.6.6.6', '8.8.8.8', '9.9.9.9'}

In [5]: ips1 | ips2 | ips3
Out[5]: {'10.20.30.40', '172.16.20.33', '192.168.1.1', '3.3.3.3', '6.6.6.6', '8.8.8.8', '9.9.9.9'}

Lo que hace es devolver un conjunto nuevo con todos los elementos que están en todos los conjuntos

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.intersection(ips2)
Out[4]: {'3.3.3.3', '8.8.8.8'}

In [5]: ips1 & ips2 & ips3
Out[5]: {'3.3.3.3'}

Lo que hace es devolver un conjunto nuevo con todos los elementos que están en todos los conjuntos

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.difference(ips2)
Out[4]: {'192.168.1.1', '6.6.6.6'}

In [5]: ips1 - ips2 - ips3
Out[5]: {'192.168.1.1'}

Lo que hace es devolver un conjunto nuevo con los elementos que están en ambos conjuntos pero no en ambos, el método solo permite operaciones entre 2 conjuntos, cuidado con el ^ (ver ejemplo).

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.symmetric_difference(ips2)
Out[4]: {'172.16.20.33', '192.168.1.1', '6.6.6.6', '9.9.9.9'}

In [5]: ips1 ^ ips2 ^ ips3
Out[5]: {'10.20.30.40', '172.16.20.33', '192.168.1.1', '3.3.3.3'}

In [6]: ips2 ^ ips3
Out[6]: {'10.20.30.40', '172.16.20.33', '6.6.6.6', '8.8.8.8'}
Importante
En el ejemplo 5, hayq ue tener en cuenta que primero hace un ips1 ^ ips2 y con el resultado hace un ^ ips3 por eso el resultado puede ser confuso.

Lo que hace es añadir al conjunto los elementos únicos de todos los conjuntos.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.update(ips2)

In [5]: ips1
Out[5]: {'172.16.20.33', '192.168.1.1', '3.3.3.3', '6.6.6.6', '8.8.8.8', '9.9.9.9'}

In [6]: ips3 |= ips2

In [7]: ips3
Out[7]: {'10.20.30.40', '172.16.20.33', '3.3.3.3', '6.6.6.6', '8.8.8.8', '9.9.9.9'}

Lo que hace es mantener en el conjunto los elementos únicos de todos los conjuntos.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.intersection_update(ips2)

In [5]: ips1
Out[5]: {'3.3.3.3', '8.8.8.8'}

In [6]: ips3 &= ips2

In [7]: ips3
Out[7]: {'3.3.3.3', '9.9.9.9'}

Lo que hace es borrar elementos del conjunto que se encuentren en los otros conjuntos. Si usamos la asignación -= se usar el signo | para separar los conjuntos.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.difference_update(ips2)

In [5]: ips1
Out[5]: {'192.168.1.1', '6.6.6.6'}

In [6]: ips3 -= ips2 | ips1

In [7]: ips3
Out[7]: {'10.20.30.40'}

Lo que hace es mantener elementos del conjunto que se encuentren en alguno de los conjuntos pero no en ambos a la vez, el método solo permite operaciones entre 2 conjuntos.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips2 = {'8.8.8.8', '172.16.20.33', '9.9.9.9', '3.3.3.3'}

In [3]: ips3 = {'9.9.9.9', '10.20.30.40', '6.6.6.6', '3.3.3.3'}

In [4]: ips1.symmetric_difference_update(ips2)

In [5]: ips1
Out[5]: {'172.16.20.33', '192.168.1.1', '6.6.6.6', '9.9.9.9'}

In [6]: ips3 ^= ips2

In [7]: ips3
Out[7]: {'10.20.30.40', '172.16.20.33', '6.6.6.6', '8.8.8.8'}

Añade un elemento al conjunto. Si el elemento ya existe no hace nada, el conjunto se mantiene intacto.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips1.add('10.20.30.40')

In [3]: ips1
Out[3]: {'10.20.30.40', '192.168.1.1', '3.3.3.3', '6.6.6.6', '8.8.8.8'}

In [4]: ips1.add('3.3.3.3')

In [5]: ips1
Out[5]: {'10.20.30.40', '192.168.1.1', '3.3.3.3', '6.6.6.6', '8.8.8.8'}

Elimina un elemento del conjunto. Si el elemento no existe se produce un error KeyError, por lo que es mejor usar .discard(elemento).

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips1.remove('192.168.1.1')

In [3]: ips1
Out[3]: {'3.3.3.3', '6.6.6.6', '8.8.8.8'}

In [4]: ips1.remove('10.20.30.40')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-4-24fcb3349e48> in <module>()
----> 1 ips1.remove('10.20.30.40')

KeyError: '10.20.30.40'

Elimina un elemento del conjunto si existe, si no, no hace nada ni se produce error.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips1.discard('192.168.1.1')

In [3]: ips1
Out[3]: {'3.3.3.3', '6.6.6.6', '8.8.8.8'}

In [4]: ips1.discard('10.20.30.40')

In [5]: ips1
Out[5]: {'3.3.3.3', '6.6.6.6', '8.8.8.8'}

Elimina un elemento de formar arbitraria del conjunto y devuelve el elemento eliminado, si el conjunto está vacío se produce un error KeyError.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips1.pop()
Out[2]: '192.168.1.1'

In [3]: ips1.pop()
Out[3]: '3.3.3.3'

In [4]: ips1.pop()
Out[4]: '6.6.6.6'

In [5]: ips1.pop()
Out[5]: '8.8.8.8'

In [6]: ips1.pop()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-a5d13ddad887> in <module>()
----> 1 ips1.pop()

KeyError: 'pop from an empty set'

Vacía un conjunto, borra todos sus elementos.

In [1]: ips1 = {'192.168.1.1', '3.3.3.3', '8.8.8.8', '6.6.6.6'}

In [2]: ips1.clear()

In [3]: ips1
Out[3]: set()

Más información: tipo de dato SET

Retro

Lugares

Redes

Sistemas

Varios