Як я можу створити набір наборів у Python?


126

Я намагаюся зробити набір наборів у Python. Я не можу зрозуміти, як це зробити.

Починаючи з порожнього набору xx:

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

але я отримую

TypeError: unhashable type: 'list'

або

TypeError: unhashable type: 'set'

Чи можливо мати набір наборів у Python?

Я маю справу з великою колекцією наборів, і я хочу мати можливість не мати справу з повторюваними наборами (набір B множин A1, A2, ...., An "скасує" два набори, якщо Ai = Aj)

Відповіді:


120

Пейтон скаржиться на те, що внутрішні setоб'єкти є змінними і, таким чином, не піддаються гріванню. Рішення полягає у використанні frozensetдля внутрішніх наборів, щоб вказати, що ви не маєте наміру змінювати їх.


59

Люди вже згадували, що ви можете це зробити із замороженим набором () , тому я просто додам код, як цього досягти:

Наприклад, ви хочете створити набір із наступного списку списків:

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

ви можете створити свій набір таким чином:

t1 = set(frozenset(i) for i in t)

9
або ви можете використовувати карту! set(map(frozenset, t))
Метт Додж

18

Використовуйте frozensetвсередині.


9
Можливо, ви могли б дати кілька покажчиків про змінні / незмінні об’єкти в Python, оскільки він новий?
Сет Джонсон

2
@Seth: Я міг би, але змінність не є фактором.
Ігнасіо Васкес-Абрамс

Дуже дякую! Просто читання re: mutability зараз. Схоже, набір списків також може працювати, але заморожений набір, здається, вдається. Знову дякую!
Метт

@Ignacio Я вважав, що члени наборів і ключів у диктатах повинні бути хеш-здатними і тому незмінними.
Сет Джонсон

7
Здатність і незмінність не обов'язково взаємовиключні. Просто так трапляється, що більшість основних типів Python поділяють закономірність.
Ігнасіо Васкес-Абрамс

3

Тож у мене була точно така ж проблема. Я хотів зробити структуру даних, яка працює як набір множин. Проблема полягає в тому, що набори повинні містити незмінні об’єкти. Отже, те, що ти можеш зробити, це просто зробити його як набір кортежів. Це добре працювало для мене!

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
У кортежах має значення порядок елементів. Таким чином A.add( (4,3,2)); A.add((2,4,3)); A.add((2,3,4))додасть три різних елемента, в той час як оригінальний питання про «безлічі множин», що означає , що (2,3,4), (4,3,2), (2,4,3)є однаковими.
Борис Горелик

1

З 2020 року офіційна документація Python радить використовувати frozensetдля представлення наборів наборів.


1
О, це дуже цікаво, враховуючи, що PEP 416 (заморожений дікт) не був прийнятий, і він був запропонований у 2012 році.
NikoNyrh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.