¿Cómo puedo crear un conjunto de conjuntos en Python?

126

Estoy tratando de hacer un conjunto de conjuntos en Python. No puedo entender cómo hacerlo.

Comenzando con el conjunto vacío xx:

xx = set([])
# Now we have some other set, for example
elements = set([2,3,4])
xx.add(elements)

pero consigo

TypeError: unhashable type: 'list'

o

TypeError: unhashable type: 'set'

¿Es posible tener un conjunto de conjuntos en Python?

Estoy tratando con una gran colección de conjuntos y quiero poder no tener que tratar conjuntos duplicados (un conjunto B de conjuntos A1, A2, ...., An "cancelaría" dos conjuntos si Ai = Aj)

Mate
fuente

Respuestas:

120

Python se queja porque los setobjetos internos son mutables y, por lo tanto, no se pueden cambiar. La solución es utilizar frozensetlos conjuntos internos para indicar que no tiene intención de modificarlos.

a3nm
fuente
59

La gente ya mencionó que puedes hacer esto con un frozenset () , así que solo agregaré un código para lograr esto:

Por ejemplo, desea crear un conjunto de conjuntos de la siguiente lista de listas:

t = [[], [1, 2], [5], [1, 2, 5], [1, 2, 3, 4], [1, 2, 3, 6]]

puedes crear tu conjunto de la siguiente manera:

t1 = set(frozenset(i) for i in t)
Salvador Dalí
fuente
9
o puedes usar el mapa! set(map(frozenset, t))
Matt Dodge
18

Usar en el frozensetinterior.

Ignacio Vazquez-Abrams
fuente
9
¿Quizás podría dar algunos consejos sobre objetos mutables / inmutables en Python ya que es nuevo?
Seth Johnson
2
@Seth: podría, pero la mutabilidad no es un factor.
Ignacio Vazquez-Abrams
¡Muchas gracias! Solo estoy leyendo re: mutabilidad ahora. Parece que un conjunto de listas también puede funcionar, pero parece que el conjunto congelado lo hace. ¡Gracias de nuevo!
Matt
@Ignacio Pensé que los miembros en conjuntos y claves en los dictos tenían que ser hash y, por lo tanto, inmutables.
Seth Johnson,
77
La hashabilidad y la mutabilidad no son necesariamente mutuamente excluyentes. Sucede que la mayoría de los tipos básicos de Python comparten un patrón.
Ignacio Vázquez-Abrams
3

Entonces tuve exactamente el mismo problema. Quería hacer una estructura de datos que funcione como un conjunto de conjuntos. El problema es que los conjuntos deben contener objetos inmutables . Entonces, lo que puedes hacer es simplemente hacerlo como un conjunto de tuplas. ¡Eso funcionó bien para mí!

A = set()
A.add( (2,3,4) )##adds the element
A.add( (2,3,4) )##does not add the same element
A.add( (2,3,5) )##adds the element, because it is different!
temblar
fuente
22
En tuplas, el orden del elemento es importante. De este modo A.add( (4,3,2)); A.add((2,4,3)); A.add((2,3,4))se sumarán tres elementos distintos, mientras que la pregunta original se trata de "conjunto de conjuntos", lo que implica que (2,3,4), (4,3,2), (2,4,3)son los mismos.
Boris Gorelik
1

A partir de 2020, la documentación oficial de Python recomienda utilizar frozensetpara representar conjuntos de conjuntos.

AtilioA
fuente
1
Wow, esto es muy interesante dado que PEP 416 (dict congelado) no se adoptó y se propuso en 2012.
NikoNyrh