`frozenset` and `frozendict` comprehensions

An alternative to changing the Python grammar for a new syntax is to add new efficient dict and set methods to convert to frozendict and frozenset. See Add a dict method to convert to a frozendict? discussion.

Regular dict and set are used to build a collection, and then .take_frozendict() or .take_frozenset() freezes the object (convert to frozendict/frozenset). These functions clear the temporary dict/set.

For example, frozendict({'x': 1, 'y': 2}) can be written {'x': 1, 'y': 2}.take_frozendict(). So instead of adding a prefix (multiple prefixes have been proposed so far!), it does add a… suffix :slight_smile:

Some examples.

Frozendict literal, when frozendict(key=value, ...) syntax cannot be used:

-_capability_names = frozendict({
+_capability_names = {
     _curses.KEY_A1: 'ka1',
     _curses.KEY_A3: 'ka3',
     _curses.KEY_B2: 'kb2',
     ...
-    })
+    }.take_frozendict()

Frozenset literal:

-    _ID_KEYWORDS = frozenset({"True", "False", "None"})
+    _ID_KEYWORDS = {"True", "False", "None"}.take_frozenset()

As a bonus, it can be more in more cases, like convert a list-comprehension to a tuple:

-        return tuple([_asdict_inner(v, dict_factory) for v in obj])
+        return [_asdict_inner(v, dict_factory) for v in obj].take_tuple()

Or convert a set-comprehension to a frozenset:

-_ATTRIB_DENY_LIST = frozenset({
+_ATTRIB_DENY_LIST = {
     name.removeprefix("assert_")
     for name in dir(NonCallableMock)
     if name.startswith("assert_")
-})
+}.take_frozenset()

See my pull request for more examples. It also adds list.take_tuple() method.

1 Like