Sets and Frozen Sets in Python — Elucidate Their Similarities and Differences

Original article was published on Artificial Intelligence on Medium

Hashability

Previously we talked about that the elements in a set and a frozenset object have to be hashable. We also talked about what data types are hashable and what are unhashable. In particular, we said that sets aren’t hashable such that a set object can’t contain any set objects. Consider the following trivial example.

>>> # Create two set objects
>>> even_numbers = set([2, 4])
>>> odd_numbers = set([1, 3])
>>>
>>> # Create a set consisting of the sets
>>> numbers_sets = set([even_numbers, odd_numbers])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

Clearly, the error tells us that the set object is unhashable. To support this statement, we can try to retrieve the hash value of a set object. Guess what will happen? Unhashable Type Error.

>>> # Create a set
>>> numbers = set([1, 2, 3])
>>>
>>> # Get the set's hash value
>>> hash(numbers)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

By contrast, the frozenset objects are hashable, certainly at the expense of being “frozen” and thus immutable for their values. Because of its hashability, a frozenset object can be an element of another set object — either set or frozenset is fine.

>>> # Create two frozen sets
>>> frozen_evens = frozenset([2, 4])
>>> frozen_odds = frozenset([1, 3])
>>>
>>> # Create a set consisting of these frozen sets
>>> numbers_sets = set([frozen_evens, frozen_odds])
>>> numbers_sets
{frozenset({2, 4}), frozenset({1, 3})}

For whatever reasons, if you need to use set objects as dictionary keys, you have to use frozenset objects because of their hashability, which is required for dictionary keys. See some pertinent code below. As you can see, a frozenset object, but not a set object, can be a key for a dictionary.

>>> # Create a set and a frozen set
>>> group0 = set(['David', 'Jennifer'])
>>> group1 = frozenset(['David', 'Jennifer'])
>>>
>>> # Create a dictionary using a set/frozenset as a key
>>> score0 = {group0: 100}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> score1 = {group1: 100}

Related to the hashability of frozenset objects, you can get their hash values using the hash() function. A trivial example is shown below.

>>> # Declare a frozen set
>>> frozen_integers = frozenset([1, 2, 3])
>>>
>>> # Get its hash value
>>> hash(frozen_integers)
-272375401224217160