7

We know in Python, a set can be defined by writing out all its elements like this:

a_set={1,"xyz"}

And books of Python all say elements of a set can be any datatype. So we should be able to write out a set containing a set. I tried to write it as:

a_set={1,{"xyz"}}

But IDLE reported an error:

Traceback (most recent call last):
  File "<pyshell#58>", line 1, in <module>
    a_set={1,{"xyz"}}
TypeError: unhashable type: 'set'

I think this may be because Python is trying to understand it as a dictionary. Then, how to write out a set containing a set in Python?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2384994
  • 1,759
  • 4
  • 24
  • 29
  • While it doesn't directly answer the question, [Why must dictionary keys be immutable?](http://docs.python.org/3.3/faq/design.html#why-must-dictionary-keys-be-immutable) in the Python FAQ is relevant here. A set's values are basically the same as a dictionary's keys (they're both stored in hash tables), so you can't put a set in a set for the same reason you can't use a dict as a dict key. – abarnert May 18 '13 at 01:07

3 Answers3

16

The inner most sets need to be of type frozenset which is an immutable version of a set.

>>> a_set = {1, frozenset(['xyz'])}
>>> a_set
set([1, frozenset(['xyz'])])

From the docs:

class frozenset([iterable])

Return a new set or frozenset object whose elements are taken from iterable. The elements of a set must be hashable. To represent sets of sets, the inner sets must be frozenset objects. If iterable is not specified, a new empty set is returned.

Community
  • 1
  • 1
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
6

Sets can only store immutable objects, while sets are mutable themselves. So a set can't contain another set.

Use a frozenset:

To represent sets of sets , the inner sets must be frozenset objects.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • 1
    It's worth noting that the limitation is that sets can only contain "hashable" objects, which are usually, but not necessarily "immutable". For example, instances of a custom classes that doesn't define `__hash__` or `__eq__` are hashable but can be mutated by assigning to attributes. This is allowed because such an object's hash is not influenced by its contents, only its identity, so it won't change if the the object is mutated. You can create objects that are partially mutable and partially immutable, and use the immutable parts to define the hash. – Blckknght May 18 '13 at 04:24
1

This example illustrates the use of frozenset:

a_set = frozenset([1,2,3])
b_set = frozenset([1,3])
a_set_copy = frozenset([2,3,1])

set_of_sets = set([a_set, b_set, a_set_copy])

print set_of_sets
# set([frozenset([1, 3]), frozenset([1, 2, 3])])
tzelleke
  • 15,023
  • 5
  • 33
  • 49