When would a frozenset be useful?
Asked Answered
A

3

13

What are some examples of when using a frozenset would be the best option?

Ashtoreth answered 12/3, 2014 at 17:43 Comment(0)
S
22

frozenset() objects can be used as dictionary keys and as values inside of set() and frozenset() objects, where set objects cannot. set() values are mutable and not hashable, frozenset() values are immutable and are hashable.

They are to set objects what tuple objects are to list objects.

Demo:

>>> s = set([1, 2])
>>> fs = frozenset(s)
>>> adict = {}
>>> adict[s] = 42   # a set as key does not work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> adict[fs] = 42  # a frozenset as key works
>>> s.add(s)        # a set as value in a set does not work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> s.add(fs)       # a frozenset as value in a set works

Recent Python versions will optimize the use of a set literal:

if somevar in {'foo', 'bar', 'baz'}:

by storing a frozenset() constant with the bytecode:

>>> import dis
>>> dis.dis(compile("if somevar in {'foo', 'bar', 'baz'}: pass", '<stdin>', 'exec'))
  1           0 LOAD_NAME                0 (somevar) 
              3 LOAD_CONST               4 (frozenset({'foo', 'baz', 'bar'})) 
              6 COMPARE_OP               6 (in) 
              9 POP_JUMP_IF_FALSE       15 
             12 JUMP_FORWARD             0 (to 15) 
        >>   15 LOAD_CONST               3 (None) 
             18 RETURN_VALUE         

because the set literal cannot be mutated anyway; this makes using sets to test against very efficient. A regular set() cannot be stored this way as that would allow you to mutate the constant stored with the byte object.

Slating answered 12/3, 2014 at 17:44 Comment(1)
I have also begun to dip my toes in .compile(). This has further solidified my understanding of this function too, personal thanks.Ashtoreth
I
5

To compliment what Martijn said, I frequently use them for cache keys. For example, a memoize decorator that would key off (args, frozenset(kwargs.items()).

Inanna answered 12/3, 2014 at 17:51 Comment(0)
P
0

I should add that unlike a tuple (which can also be used as a dict key or set member because it's hashable), a frozenset is unordered, making it handy for cases where you don't care about ordering the items.

here is a detailed example, see dbramucci's post.

Palma answered 13/1, 2023 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.