Jak mogę stworzyć zestaw zestawów w Pythonie?

126

Próbuję stworzyć zestaw zestawów w Pythonie. Nie wiem, jak to zrobić.

Począwszy od pustego zestawu xx:

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

ale dostaję

TypeError: unhashable type: 'list'

lub

TypeError: unhashable type: 'set'

Czy można mieć zestaw zestawów w Pythonie?

Mam do czynienia z dużą kolekcją zestawów i chcę być w stanie nie mieć do czynienia z duplikatami zestawów (zestaw B zestawów A1, A2, ...., An „anulowałby” dwa zestawy, jeśli Ai = Aj)

Matt
źródło

Odpowiedzi:

120

Python narzeka, ponieważ setobiekty wewnętrzne są zmienne, a zatem nie można ich hashować. Rozwiązaniem jest użycie frozensetdla zestawów wewnętrznych, aby wskazać, że nie masz zamiaru ich modyfikować.

a3nm
źródło
59

Ludzie już wspominali, że można to zrobić za pomocą frozenset () , więc dodam tylko kod, jak to osiągnąć:

Na przykład chcesz utworzyć zestaw zestawów z poniższej listy list:

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

zestaw możesz stworzyć w następujący sposób:

t1 = set(frozenset(i) for i in t)
Salvador Dali
źródło
9
lub możesz użyć mapy! set(map(frozenset, t))
Matt Dodge,
18

Użyj frozensetwewnątrz.

Ignacio Vazquez-Abrams
źródło
9
Być może mógłbyś dać kilka wskazówek na temat obiektów modyfikowalnych / niezmiennych w Pythonie, ponieważ jest nowy?
Seth Johnson
2
@Seth: Mógłbym, ale zmienność nie jest czynnikiem.
Ignacio Vazquez-Abrams
Dziękuję bardzo! Właśnie czytam re: mutability teraz. Wygląda na to, że zestaw list może również działać, ale Frozenset wydaje się to robić. Dzięki jeszcze raz!
Matt
@Ignacio Pomyślałem, że składowe w zestawach i klucze w dyktach muszą mieć możliwość mieszania, a zatem są niezmienne.
Seth Johnson
7
Hashability i mutability niekoniecznie wykluczają się wzajemnie. Tak się składa, że ​​większość podstawowych typów Pythona ma wspólny wzorzec.
Ignacio Vazquez-Abrams
3

Więc miałem dokładnie ten sam problem. Chciałem stworzyć strukturę danych, która będzie działać jako zbiór zestawów. Problem polega na tym, że zbiory muszą zawierać niezmienne obiekty. Możesz więc po prostu utworzyć zestaw krotek. To działało dobrze dla mnie!

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!
drżenie
źródło
22
W krotkach kolejność elementów ma znaczenie. Zatem A.add( (4,3,2)); A.add((2,4,3)); A.add((2,3,4))doda trzy odrębne elementy, podczas gdy oryginalne pytanie jest o „zestaw zestawów”, co oznacza, że (2,3,4), (4,3,2), (2,4,3)są takie same.
Boris Gorelik
1

Od 2020 roku oficjalna dokumentacja Pythona zaleca używanie frozensetdo reprezentowania zestawów zestawów.

AtilioA
źródło
1
Wow, to bardzo interesujące, biorąc pod uwagę, że PEP 416 (zamrożony dykt) nie został przyjęty i został zaproponowany w 2012 roku.
NikoNyrh