
+1 I would appreciate being able to create a frozenset using f{1, 2, 3}. This will also make the `repr` of frozensets shorter. On Sun, Jan 16, 2022 at 10:33 AM Steven D'Aprano <steve@pearwood.info> wrote:
Inspired by this enhancement request:
https://bugs.python.org/issue46393
I thought it might be time to revist the idea of a frozenset display. This has been discussed a few times before, such as here:
https://mail.python.org/pipermail/python-ideas/2018-July/051902.html
We have displays for the most important builtin data structures:
- lists [1, 2, 3] - tuples (1, 2, 3) - dicts {1: 0, 2: 0, 3: 0} - sets {1, 2, 3}
(as well as literals for ints, floats, strings and bytes)
but not for frozensets. So the only way to guarantee that you have a frozenset is to explicitly call the builtin, which is not only a runtime call rather than a compile-time operation, but can be monkey-patched or shadowed.
CPython already has some neat optimizations in place to use frozensets instead of sets, for example:
import dis dis.dis("x in {1, 2, 3}") 1 0 LOAD_NAME 0 (x) 2 LOAD_CONST 0 (frozenset({1, 2, 3})) 4 CONTAINS_OP 0 6 RETURN_VALUE
and the compiler can build frozensets of literals as a constant. Ironically, this means that actually making a frozenset explicitly does far more work than needed:
dis.dis("frozenset({1, 2, 3})") 1 0 LOAD_NAME 0 (frozenset) 2 BUILD_SET 0 4 LOAD_CONST 0 (frozenset({1, 2, 3})) 6 SET_UPDATE 1 8 CALL_FUNCTION 1 10 RETURN_VALUE
Got that? To create a frozenset of literals, first the compiler creates a frozenset constant containing what you wanted. Then at runtime, it:
- looks up frozenset in globals and builtins; - loads the pre-prepared frozenset (which is exactly what we want); - creates a new set from that frozenset; - calls the frozenset() function on that set to create a new frozenset that duplicates the pre-prepared one; - and finally garbage-collects the temporary set.
So to get the frozenset we want, we start with the frozenset we want, and make an unnecessary copy the long way o_O
If you didn't know that every step in that song and dance routine was necessary, it would seem ludicrously wasteful.
If we had a frozenset display, we could avoid most of that work, optimizing that down to a LOAD_CONST like this:
dis.dis('(1, 2, 3)') 1 0 LOAD_CONST 0 ((1, 2, 3)) 2 RETURN_VALUE
It seems to me that all of the machinery to make this work already exists. The compiler already knows how to create frozensets at compile-time, avoiding the need to lookup and call the frozenset() builtin. All we need is syntax for a frozenset display.
How does this work for you?
f{1, 2, 3}
-- Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/GRMNMW... Code of Conduct: http://python.org/psf/codeofconduct/