Как я могу создать набор наборов в 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)

Ответы:


121

Python жалуется, потому что внутренние setобъекты изменчивы и, следовательно, не могут быть хешированы. Решение - использовать frozensetдля внутренних наборов, чтобы указать, что вы не собираетесь их изменять.


59

Люди уже упоминали, что вы можете сделать это с помощью frozenset () , поэтому я просто добавлю код, как этого добиться:

Например, вы хотите создать набор наборов из следующего списка списков:

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. Похоже, что набор списков тоже может работать, но Frozenset, кажется, справляется. Еще раз спасибо!
Мэтт

@Ignacio Я думал, что элементы в наборах и ключи в dicts должны быть хешируемыми и, следовательно, неизменными.
Сет Джонсон,

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)являются одинаковыми.
Борис Горелик

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.