Como posso criar um conjunto de conjuntos em Python?

126

Estou tentando fazer um conjunto de conjuntos em Python. Não consigo descobrir como fazê-lo.

Começando com o conjunto vazio xx:

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

mas eu entendo

TypeError: unhashable type: 'list'

ou

TypeError: unhashable type: 'set'

É possível ter um conjunto de conjuntos em Python?

Estou lidando com uma grande coleção de conjuntos e quero poder não precisar lidar com conjuntos duplicados (um conjunto B dos conjuntos A1, A2, ...., e "cancelaria" dois conjuntos se Ai = Aj)

Matt
fonte

Respostas:

120

O Python está reclamando porque os setobjetos internos são mutáveis ​​e, portanto, não podem ser lavados. A solução é usar frozensetpara os conjuntos internos, para indicar que você não tem intenção de modificá-los.

a3nm
fonte
59

As pessoas já mencionaram que você pode fazer isso com um frozenset () , então vou adicionar um código de como fazer isso:

Por exemplo, você deseja criar um conjunto de conjuntos da seguinte lista de listas:

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

você pode criar seu conjunto da seguinte maneira:

t1 = set(frozenset(i) for i in t)
Salvador Dalí
fonte
9
ou você pode usar o mapa! set(map(frozenset, t))
Matt Dodge
18

Use frozensetdentro.

Ignacio Vazquez-Abrams
fonte
9
Talvez você possa dar algumas dicas sobre objetos mutáveis ​​/ imutáveis ​​em Python, já que ele é novo?
Seth Johnson
2
@ Set: Eu poderia, mas a mutabilidade não é um fator.
Ignacio Vazquez-Abrams
Muito obrigado! Apenas lendo re: mutability agora. Parece que um conjunto de listas também pode funcionar, mas o frozenset parece fazê-lo. Obrigado novamente!
Matt
@Ignacio Eu pensei que os membros de conjuntos e chaves nos ditados tinham que ser hashable e, portanto, imutáveis.
Seth Johnson
7
Hashability e mutabilidade não são necessariamente mutuamente exclusivas. Acontece que a maioria dos tipos básicos de Python compartilham um padrão.
Ignacio Vazquez-Abrams
3

Então, eu tive exatamente o mesmo problema. Eu queria criar uma estrutura de dados que funcionasse como um conjunto de conjuntos. O problema é que os conjuntos devem conter objetos imutáveis . Então, o que você pode fazer é simplesmente fazer isso como um conjunto de tuplas. Isso funcionou bem para mim!

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!
tremer
fonte
22
Nas tuplas, a ordem dos elementos é importante. Assim A.add( (4,3,2)); A.add((2,4,3)); A.add((2,3,4))irá adicionar três elementos distintos, enquanto que a pergunta original é sobre "conjunto de conjuntos", o que implica que (2,3,4), (4,3,2), (2,4,3)são os mesmos.
Boris Gorelik 28/02
1

A partir de 2020, a documentação oficial do Python recomenda o uso frozensetpara representar conjuntos de conjuntos.

AtilioA
fonte
1
Uau, isso é muito interessante, uma vez que o PEP 416 (ditado congelado) não foi adotado e foi proposto em 2012.
NikoNyrh