Comment créer un ensemble d'ensembles en Python?

126

J'essaie de créer un ensemble d'ensembles en Python. Je ne sais pas comment faire.

En commençant par l'ensemble vide xx:

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

mais je reçois

TypeError: unhashable type: 'list'

ou

TypeError: unhashable type: 'set'

Est-il possible d'avoir un ensemble d'ensembles en Python?

J'ai affaire à une grande collection d'ensembles et je veux pouvoir ne pas avoir à traiter d'ensembles en double (un ensemble B d'ensembles A1, A2, ...., An "annulerait" deux ensembles si Ai = Aj)

Mat
la source

Réponses:

121

Python se plaint parce que les setobjets internes sont mutables et donc non hachables. La solution est d'utiliser frozensetpour les ensembles internes, pour indiquer que vous n'avez pas l'intention de les modifier.

a3nm
la source
59

Les gens ont déjà mentionné que vous pouvez le faire avec un frozenset () , je vais donc simplement ajouter un code pour y parvenir:

Par exemple, vous souhaitez créer un ensemble d'ensembles à partir de la liste de listes suivante:

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

vous pouvez créer votre ensemble de la manière suivante:

t1 = set(frozenset(i) for i in t)
Salvador Dali
la source
9
ou vous pouvez utiliser la carte! set(map(frozenset, t))
Matt Dodge
18

Utilisez à l' frozensetintérieur.

Ignacio Vazquez-Abrams
la source
9
Peut-être pourriez-vous donner quelques conseils sur les objets mutables / immuables en Python depuis qu'il est nouveau?
Seth Johnson
2
@Seth: Je pourrais, mais la mutabilité n'est pas un facteur.
Ignacio Vazquez-Abrams
Merci beaucoup! Juste lire re: mutabilité maintenant. On dirait qu'un ensemble de listes peut également fonctionner, mais frozenset semble le faire. Merci encore!
Matt
@Ignacio Je pensais que les membres dans les ensembles et les clés dans les dictionnaires devaient être hachables et donc immuables.
Seth Johnson
7
Hashabilité et mutabilité ne s'excluent pas nécessairement mutuellement. Il se trouve que la plupart des types Python de base partagent un modèle.
Ignacio Vazquez-Abrams
3

J'ai donc eu exactement le même problème. Je voulais créer une structure de données qui fonctionne comme un ensemble d'ensembles. Le problème est que les ensembles doivent contenir des objets immuables . Donc, ce que vous pouvez faire, c'est simplement en faire un ensemble de tuples. Cela a bien fonctionné pour moi!

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!
tremb
la source
22
Dans les tuples, l'ordre des éléments est important. Ainsi A.add( (4,3,2)); A.add((2,4,3)); A.add((2,3,4))ajoutera trois éléments distincts, alors que la question initiale est de « ensemble d'ensembles », ce qui implique que (2,3,4), (4,3,2), (2,4,3)sont les mêmes.
Boris Gorelik
1

À partir de 2020, la documentation officielle de Python conseille d'utiliser frozensetpour représenter des ensembles d'ensembles.

AtilioA
la source
1
Wow, c'est très intéressant étant donné que la PEP 416 (dictée gelée) n'a pas été adoptée et qu'elle a été proposée en 2012.
NikoNyrh le