5.4. Sequence Frozenset

5.4.1. Rationale

  • Only unique values

  • Immutable - cannot add, modify or remove items

  • Can store elements of any hashable types

  • Has all set methods such as .intersect(), .subset() .union(), etc.

  • One solid block in memory

  • Frozenset is unordered data structure and do not record element position

  • Do not support getitem and slice

5.4.2. Definition

Defining only with frozenset() - no short syntax:

>>> data = frozenset()

Comma after last element of a one element frozenset is optional:

>>> data = frozenset({1})
>>> data = frozenset({1,})

Brackets inside are required:

>>> data = frozenset({1})
>>> data = frozenset({1, 2, 3})
>>> data = frozenset({1.1, 2.2, 3.3})
>>> data = frozenset({True, False})
>>> data = frozenset({'a', 'b', 'c'})
>>> data = frozenset({'a', 1, 2.2, True, None})

5.4.3. Type Casting

Builtin function frozenset() converts argument to frozenset

>>> data = 'abcd'
>>> frozenset(data) == frozenset({'a', 'b', 'c', 'd'})
True
>>> data = ['a', 'b', 'c', 'd']
>>> frozenset(data) == frozenset({'a', 'b', 'c', 'd'})
True
>>> data = ('a', 'b', 'c', 'd')
>>> frozenset(data) == frozenset({'a', 'b', 'c', 'd'})
True
>>> data = {'a', 'b', 'c', 'd'}
>>> frozenset(data) == frozenset({'a', 'b', 'c', 'd'})
True
>>> data = frozenset({'a', 'b', 'c', 'd'})
>>> frozenset(data) == frozenset({'a', 'b', 'c', 'd'})
True
>>> data = [1, 2, 3, [4, 5]]
>>> frozenset(data)
Traceback (most recent call last):
TypeError: unhashable type: 'list'
>>> data = [1, 2, 3, (4, 5)]
>>> frozenset(data) == frozenset({(4, 5), 1, 2, 3})
True

5.4.4. Frozenset vs. Set

Both:

  • unordered

  • impossible to getitem and slice

  • unique elements

  • only hashable elements

Frozenset:

  • immutable

Set:

  • mutable

Memory Footprint:

>>> from sys import getsizeof
>>>
>>> a = {1, 2, 3}
>>> b = frozenset({1, 2, 3})
>>>
>>> getsizeof(a)
216
>>>
>>> getsizeof(b)
216

5.4.5. Assignments

Code 5.9. Solution
"""
* Assignment: Sequence Frozenset Create
* Required: no
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min

English:
    1. Create frozenset `result` with elements:
        a. `'a'`
        b. `1`
        c. `2.2`
    2. Run doctests - all must succeed

Polish:
    1. Stwórz frozenset `result` z elementami:
        a. `'a'`
        b. `1`
        c. `2.2`
    2. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'
    >>> assert type(result) is frozenset, \
    'Variable `result` has invalid type, should be frozenset'
    >>> assert len(result) == 3, \
    'Variable `result` length should be 3'

    >>> 'a' in result
    True
    >>> 1 in result
    True
    >>> 2.2 in result
    True
"""

# frozenset[str|int|float]: with 'a' and 1 and 2.2
result = ...

Code 5.10. Solution
"""
* Assignment: Sequence Frozenset Split
* Required: no
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
    1. Define `result: frozenset`
    2. Split lines and convert result to frozenset
    3. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result: frozenset`
    2. Podziel linie i przekonwertuj wynik do frozenset
    3. Uruchom doctesty - wszystkie muszą się powieść

Hint:
    * `str.splitlines()`

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'

    >>> assert len(result) == 3, \
    'Variable `result` length should be 3'

    >>> assert type(result) is frozenset, \
    'Variable `result` has invalid type, should be frozenset'

    >>> line = 'We choose to go to the Moon'
    >>> assert line in result, f'Line "{line}" is not in the result'

    >>> line = 'in this decade and do the other things.'
    >>> assert line in result, f'Line "{line}" is not in the result'

    >>> line = 'Not because they are easy, but because they are hard.'
    >>> assert line in result, f'Line "{line}" is not in the result'
"""

DATA = """We choose to go to the Moon
in this decade and do the other things.
Not because they are easy, but because they are hard."""

# frozenset[str]: with DATA split by lines
result = ...

Code 5.11. Solution
"""
* Assignment: Sequence Frozenset Join
* Required: no
* Complexity: easy
* Lines of code: 1 lines
* Time: 3 min

English:
    1. Define `result: str`
    2. Use `str.join()` to join lines of text with newline (`\n`) character
    3. Run doctests - all must succeed

Polish:
    1. Zdefiniuj `result: str`
    2. Użyj `str.join()` aby połączyć linie tekstu znakiem końca linii (`\n`)
    3. Uruchom doctesty - wszystkie muszą się powieść

Hint:
    * `str.join()`

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert result is not Ellipsis, \
    'Assign result to variable: `result`'

    >>> assert type(result) is str, \
    'Variable `result` has invalid type, should be str'

    >>> assert result.count('\\n') == 2, \
    'There should be only two newline characters in result'

    >>> line = 'We choose to go to the Moon'
    >>> assert line in result, f'Line "{line}" is not in the result'

    >>> line = 'in this decade and do the other things.'
    >>> assert line in result, f'Line "{line}" is not in the result'

    >>> line = 'Not because they are easy, but because they are hard.'
    >>> assert line in result, f'Line "{line}" is not in the result'
"""

DATA = frozenset({
    'We choose to go to the Moon',
    'in this decade and do the other things.',
    'Not because they are easy, but because they are hard.'})

# str: with lines from DATA joined with newline (`\n`) character
result = ...