Why aren’t Python sets hashable?

I stumbled across a blog post detailing how to implement a powerset function in Python. So I went about trying my own way of doing it, and discovered that Python apparently cannot have a set of sets, since set is not hashable. This is irksome, since the definition of a powerset is that it is a set of sets, and I wanted to implement it using actual set operations.

>>> set([ set() ])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

Is there a good reason Python sets are not hashable?

Immutable objects are not hashable in python?

I heard about the line immutable objects are hashable, below like this, Frozensets are immutable and always hashable. But tuples are immutable but not hashable? Why?

Set of non hashable objects in python

Is there an equivalent to python set for non-hashable objects? (For instance custom class that can be compared to one another but not hashed?)

A hashable, flexible identifier in python

I’m trying to make some sort of hashable identifier in python; I need it to identify nodes in a graph. The trouble is that some nodes have different attributes. If the attributes of these nodes are po

Dict not hashable python

I looked online and cant seem to understand much of it. im new to python and was wondering how i can fix this. when running: results = getRecommendations(userCompare[0], userCompare[0][‘1’], sim_dist

Making a python user-defined class sortable, hashable

What methods need to be overridden/implemented when making user-defined classes sortable and/or hashable in python? What are the gotchas to watch out for? I type dir({}) into my interpreter to get a l

Using non-hashable Python objects as keys in dictionaries

Python doesn’t allow non-hashable objects to be used as keys in other dictionaries. As pointed out by Andrey Vlasovskikh, there is a nice workaround for the special case of using non-nested dictionari

Why there is no Hashable interface in Java

Object in Java has hashCode method, however, it is being used only in associative containers like HashSet or HashMap. Why was it designed like that? Hashable interface having hashCode method looks as

what do you mean by hashable in python

I tried searching internet but could not find the meaning of hashable. When they say objects are hashable or hashable objects what does it mean

Hashable, immutable

From a recent SO question (see Create a dictionary in python which is indexed by lists) I realized I probably had a wrong conception of the meaning of hashable and immutable objects in python. What do

Why are sets bigger than lists in python?

Why is the size of sets in Python noticeably larger than that of lists with same elements? a = set(range(10000)) b = list(range(10000)) print(‘set size = ‘, a.__sizeof__()) print(‘list size = ‘, b.__s

Answers

Because they’re mutable.

If they were hashable, a hash could silently become “invalid”, and that would pretty much make hashing pointless.

Generally, only immutable objects are hashable in Python. The immutable variant of set() — frozenset() — is hashable.

From the Python docs:

hashable
An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash() method), and can be compared to other objects (it needs an eq() or cmp() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal, and their hash value is their id().

In case this helps… if you really need to convert unhashable things into hashable equivalents for some reason you might do something like this:

from collections import Hashable, MutableSet, MutableSequence, MutableMapping

def make_hashdict(value):
    """
    Inspired by http://stackoverflow.com/questions/1151658/python-hashable-dicts
     - with the added bonus that it inherits from the dict type of value
       so OrderedDict's maintain their order and other subclasses of dict() maintain their attributes
    """
    map_type = type(value)

    class HashableDict(map_type):
        def __init__(self, *args, **kwargs):
            super(HashableDict, self).__init__(*args, **kwargs)
        def __hash__(self):
            return hash(tuple(sorted(self.items())))

    hashDict = HashableDict(value)

    return hashDict


def make_hashable(value):
    if not isinstance(value, Hashable):
        if isinstance(value, MutableSet):
            value = frozenset(value)
        elif isinstance(value, MutableSequence):
            value = tuple(value)
        elif isinstance(value, MutableMapping):
            value = make_hashdict(value)

        return value

my_set = set()
my_set.add(make_hashable(['a', 'list']))
my_set.add(make_hashable({'a': 1, 'dict': 2}))
my_set.add(make_hashable({'a', 'new', 'set'}))

print my_set

My HashableDict implementation is the simplest and least rigorous example from here. If you need a more advanced HashableDict that supports pickling and other things, check the many other implementations. In my version above I wanted to preserve the original dict class, thus preserving the order of OrderedDicts. I also use AttrDict from here for attribute-like access.

My example above is not in any way authoritative, just my solution to a similar problem where I needed to store some things in a set and needed to “hashify” them first.