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)

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ć.


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)

9
lub możesz użyć mapy! set(map(frozenset, t))
Matt Dodge,

18

Użyj frozensetwewnątrz.


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!

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.