_______ __ _______
| | |.---.-..----.| |--..-----..----. | | |.-----..--.--.--..-----.
| || _ || __|| < | -__|| _| | || -__|| | | ||__ --|
|___|___||___._||____||__|__||_____||__| |__|____||_____||________||_____|
on Gopher (inofficial)
(HTM) Visit Hacker News on the Web
COMMENT PAGE FOR:
(HTM) A âfrozenâ dictionary for Python
whimsicalism wrote 1 hour 3 min ago:
yes! no more `MappingProxyType` hacks
rurban wrote 1 hour 32 min ago:
> so having a safe way to share dictionaries between threads will be a
boon
Since only the keys are const, the values not, frozendict is not
thread-safe per se. There needs to be a small lock around the value
getter and setter.
varelaz wrote 1 hour 11 min ago:
it's thread safe on operations on the dict but not on the values.
Same relates to other immutable structures like tuples. Lock will not
help here cause unsafety comes from operation on value after value is
obtained.
the__alchemist wrote 2 hours 41 min ago:
I wish Python could move away from types-as-mutability-determiners. Or
paper over them; all could have mutable and non-mutable variants, with
"to_mut()" and "to_immut()" methods. And in the same vein, explicit
control over whether functions mutate a variable in place, or make a
local copy. Python is my first lang, and I still am unable to
consistently reason about these.
perrygeo wrote 2 hours 57 min ago:
Python discovers immutable data, and gets it wrong. Frozendict is a
blunt instrument - instead of a mutable free-for-all, it just locks the
data for the entire lifecycle. Brace for the wave of code littered with
deep copies, proudly proclaiming how functional it all is.
If you want real immutable data structures, not a cheap imitation,
check out pyrsistent.
cylemons wrote 2 hours 42 min ago:
How else would you "modify" immutable data other than by copying it?
thechao wrote 2 hours 33 min ago:
And, yet, somehow, functional languages have been doing this since
forever? I jest, I jest! There's an entire field of study focused
on this! I'm no expert, but imagine you've got a singly-linked
list, and we're going to allow only push_back() and pull_back() (no
insert()). Let's go ahead and let multiple owners have at this
list. If A does "pull_back()" what really happens is A has a local
"tail" pointer that moves back along the end of the list and has a
new belief about the end of the list. When A does "push_back()" it
begins attaching links at its new tail. Since the links just "point
backwards" without modifying the old links, this doesn't mutate the
list "as is", it only mutates A's version of the list. So, if B is
also looking at the list, it could just start doing "push_back()"
and add its own "tail". The result is a data-structure that's a
"bunch of shared singly linked lists" in a bush structure that's
more akin to a tree than a singly linked list.
You can do the same thing with binary trees and other structures.
It's more fiddly, and there's definitely places where
single-ownership allows mutability "under the hood" for real
performance gains, but that's the basic idea.
ndr wrote 2 hours 35 min ago:
You don't have to copy everything.
Look up persistent data structures [0]
The main trick is to store everything in a tree with a large
branching factor.
The elements are on your leaves.
When you want to make an edit you need to create only the nodes
from the root to the actual leaf. Then you return the new root.
Everything else you can share.
This is a log operation, normally implemented with branch 32.
It works with vectors as well as dicts.
Creating a copy is constant, it's immutable can be shared freely
(especially on GC'd languages).
Insert/Delete are O(log32(n)) instead of O(n) they'd be with a full
copy.
[0]
(HTM) [1]: https://en.wikipedia.org/wiki/Persistent_data_structure#Pe...
shadowgovt wrote 2 hours 47 min ago:
If your dicts are frozen, you shouldn't need to deep-copy. The point
of immutability is that if you want a new frozendict based on another
one, you just rebuild the indirection data structure up top and leave
the values it references alone.
perrygeo wrote 1 hour 1 min ago:
You're absolutely right: an "indirection data structure" is
necessary. Freezing the data is the least interesting part - it
doesn't give you any of the benefits typically associated with
immutable data structures in functional languages. That's my point
- Python is shipping a half solution that's being mistaken for a
proper one.
You think Python developers are going to roll their own HAMT on top
of frozendicts? Or are they just gonna make copies? Personally, I'd
just use pyrsistent which seems to get it right.
ok123456 wrote 3 hours 23 min ago:
Ruby has had frozen dictionaries since version 1.0, and they are
generally considered a good thing to use where possible.
Strilanc wrote 3 hours 25 min ago:
This is a type that I would use a lot.
For example, I often write classes that do cacheable analysis that
results in a dict (e.g. the class stores a list of tiles defined by
points and users want a point-to-tiles mapping for convenience). It's
worth caching those transformations, e.g. using
@functools.cached_property, but this introduces a risk where any caller
could ruin the returned cached value by editing it. Currently, I take
the safety hit (cache a dict) instead of the performance hit (make a
new copy for each caller). Caching a frozendict would be a better
tradeoff.
clickety_clack wrote 3 hours 0 min ago:
Maybe you should take a look at pyrsistent. That allows you to make
frozen âmapsâ. You can âevolveâ them into new versions of the
objects and it keeps the references to the unchanged keys and values
under the hood so itâs fast and memory efficient.
mwsherman wrote 3 hours 42 min ago:
Iâve found C#âs frozen dictionary to be useful: [1] Itâs
optimized for fast reads in exchange for expensive creation.
(HTM) [1]: https://learn.microsoft.com/en-us/dotnet/api/system.collection...
sevensor wrote 4 hours 22 min ago:
Concurrency is a good motivation, but this is super useful even in
straight line code. Thereâs a huge difference between functions that
might mutate a dictionary you pass in to them and functions that
definitely wonât. Using Mapping is great, but itâs a shallow
guarantee because you can violate it at run time.
xamuel wrote 4 hours 26 min ago:
This subject always seems to get bogged down in discussions about
ordered vs. unordered keys, which to me seems totally irrelevant.
No-one seems to mention the glaring shortcoming which is that, since
dictionary keys are required to be hashable, Python has the bizarre
situation where dicts cannot be dict keys, as in...
{{'foo': 'bar'}: 1, {3:4, 5:6}: 7}
...and there is no reasonable builtin way to get around this!
You may ask: "Why on earth would you ever want a dictionary with
dictionaries for its keys?"
More generally, sometimes you have an array, and for whatever reason,
it is convenient to use its members as keys. Sometimes, the array in
question happens to be an array of dicts. Bang, suddenly it's
impossible to use said array's elements as keys! I'm not sure what
infuriates me more: said impossibility, or the python community's
collective attitude that "that never happens or is needed, therefore no
frozendict for you"
kzrdude wrote 4 hours 12 min ago:
Turning a dictionary into a tuple of tuples `((k1, v1), (k2, v2),
...)`; isn't that a reasonable way?
If you want to have hash map keys, you need to think about how to
hash them and how to compare for equality, it's just that. There will
be complications to that such as floats, which have a tricky notion
of equality, or in Python mutable collections which don't want to be
hashable.
xamuel wrote 2 hours 52 min ago:
That argument would apply to sets too, and yet frozenset is
builtin.
lou1306 wrote 4 hours 29 min ago:
Can someone give a strong rationale for a separate built-in class?
Because "it prevents any unintended modifications" is a bit weak.
If you have fixed keys, a frozen dataclass will do. If you don't, you
can always start with a normal dict d, then store
tuple(sorted(d.items())) to have immutability and efficient lookups
(binary search), then throw away d.
bilsbie wrote 4 hours 54 min ago:
Wow weird Mandela effect for me. I really remember this being a built
and actually using it.
aewens wrote 4 hours 33 min ago:
You may be thinking of the `frozenset()` built in or the third party
Python module [frozendict]( [1] )?
Personally, Iâve been using a wrapper around
`collections.namedtuple` as an underlying data structure to create
frozen dictionaries when Iâve needed something like that for a
project.
(HTM) [1]: https://pypi.org/project/frozendict/
guidopallemans wrote 4 hours 12 min ago:
When you are making str -> Any dictionaries it's quite likely
you're better off with dataclasses or namedtuples anyway.
TheFlyingFish wrote 3 hours 31 min ago:
That works if you're dealing with a known set of keys (i.e. what
most statically-typed languages would call a struct). It falls
down if you need something where the keys are unknowable until
runtime, like a lookup table.
I do like dataclasses, though. I find them sneaking into my code
more and more as time goes on. Having a declared set of
properties is really useful, and it doesn't hurt either that
they're syntactically nicer to use.
hiddencost wrote 4 hours 38 min ago:
Perhaps immutabledict?
(HTM) [1]: https://pypi.org/project/immutabledict/
pansa2 wrote 4 hours 42 min ago:
There was a previous PEP (in 2012) with the exact same title: [1]
Also one in 2019 for a "frozenmap":
(HTM) [1]: https://peps.python.org/pep-0416/
(HTM) [2]: https://peps.python.org/pep-0603/
Qem wrote 4 hours 46 min ago:
Perhaps you used the frozen dict implementation from the pip
installable boltons library:
(HTM) [1]: https://boltons.readthedocs.io/en/latest/dictutils.html#bolt...
zzzeek wrote 5 hours 11 min ago:
SQLAlchemy has its own frozendict which we've had in use for many
years, we have it as a pretty well performing cython implementation
these days, and I use it ubiquitously. Would be a very welcome
addition to the stdlib.
This proposal is important enough that I chimed in on the thread with a
detailed example of how SQLAlchemy uses this pattern:
(HTM) [1]: https://discuss.python.org/t/pep-814-add-frozendict-built-in-t...
pansa2 wrote 5 hours 14 min ago:
I wonder whether Raymond Hettinger has an opinion on this PEP. A long
time ago, he wrote: "freezing dicts is a can of worms and not
especially useful".
(HTM) [1]: https://mail.python.org/pipermail/python-dev/2006-February/060...
morshu9001 wrote 2 min ago:
I agree, same with frozenset. If you really want to use one of those
as a key, convert to a tuple. There might be niche use cases for all
this, but it's not something that the language or even the standard
lib need to support.
ndr wrote 3 hours 0 min ago:
Immutability it's a joy to work with. Ask anyone who's worked with
Clojure's dicts.
dkarl wrote 3 hours 46 min ago:
It's interesting that he concludes that freezing dicts is "not
especially useful" after addressing only a single motivation: the use
of a dictionary as a key.
He doesn't address the reason that most of us in 2025 immediately
think of, which is that it's easier to reason about code if you know
that certain values can't change after they're created.
What a change in culture over the last 20 years!
zahlman wrote 4 hours 35 min ago:
> Another PEP 351 world view is that tuples can serve as frozenlists;
however,
that view represents a Liskov violation (tuples don't support the
same
methods). This idea resurfaces and has be shot down again every few
months.
... Well, yes; it doesn't support the methods for mutation. Thinking
of ImmutableFoo as a subclass of Foo is never going to work. And,
indeed, `set` and `frozenset` don't have an inheritance relationship.
I normally find Hettinger very insightful so this one is
disappointing. But nobody's perfect, and we change over time (and so
do the underlying conditions). I've felt like frozendict was missing
for a long time, though. And really I think the language would have
been better with a more formal concept of immutability (e.g. linking
it more explicitly to hashability; having explicit recognition of
"cache" attributes, ...), even if it didn't go the
immutable-by-default route.
kccqzy wrote 3 hours 15 min ago:
Apple (or perhaps NeXT) has solved this problem already in
Objective-C. Look at NSArray and NSMutableArray, or NSData and
NSMutableData. Itâs intuitive and Liskov-correct to make the
mutable version a subclass of the immutable version. And itâs
clearly wrong to have the subclass relationship the other way
around.
Given how dynamic Python is, such a subclass relationship need not
be evident at the C level. You can totally make one class whose
implementation is independent of another class a subclass of the
other, using PEP 3119. This gives implementations complete
flexibility in how to implement the class while retaining the
ontological subclass relationship.
pansa2 wrote 4 hours 22 min ago:
> ImmutableFoo as a subclass of Foo is never going to work. And,
indeed, `set` and `frozenset` don't have an inheritance
relationship.
Theoretically, could `set` be a subclass of `frozenset` (and `dict`
of `frozendict`)? Do other languages take that approach?
> linking [immutability] more explicitly to hashability
AFAIK immutability and hashability are equivalent for the
language's "core" types. Would it be possible to enforce that
equivalence for user-defined types, given that mutability and the
implementation of `__hash__` are entirely controlled by the
programmer?
kccqzy wrote 3 hours 13 min ago:
Yes you could. Other languages do. See NSMutableSet and NSSet in
Objective-C.
chriswarbo wrote 4 hours 7 min ago:
> Theoretically, could `set` be a subclass of `frozenset` (and
`dict` of `frozendict`)?
At one extreme: sure, anything can be made a subclass of anything
else, if we wanted to.
At the other extreme: no, since Liskov substitution is an
impossibly-high bar to reach; especially in a language that's as
dynamic/loose as Python. For example, consider an expression like
'"pop" in dir(mySet)'
tremon wrote 3 hours 48 min ago:
> consider an expression like '"pop" in dir(mySet)'
class frozenset:
pass
class set(frozenset):
def pop(self, key):
pass
I don't see why hasattr(mySet, 'pop') should be a problem here?
jonathaneunice wrote 4 hours 46 min ago:
That's a great link and recommended reading.
It explains a lot about the design of Python container classes, and
the boundaries of polymorphism / duck typing with them, and mutation
between them.
I don't always agree with the choices made in Python's container
APIs...but I always want to understand them as well as possible.
Also worth noting that understanding changes over time. Remember when
GvR and the rest of the core developers argued adamantly against
ordered dictionaries? Haha! Good times! Thank goodness their first
wave of understanding wasn't their last. Concurrency and parallelism
in Python was a TINY issue in 2006, but at the forefront of Python
evolution these days. And immutability has come a long way as a
design theme, even for languages that fully embrace stateful change.
zahlman wrote 4 hours 34 min ago:
> Also worth noting that understanding changes over time. Remember
when GvR and the rest of the core developers argued adamantly
against ordered dictionaries? Haha! Good times!
The new implementation has saved space, but there are opportunities
to save more space (specifically after deleting keys) that they've
now denied themselves by offering the ordering guarantee.
jonathaneunice wrote 4 hours 7 min ago:
Ordering, like stability in sorting, is an incredibly useful
property. If it costs a little, then so be it.
This is optimizing for the common case, where memory is generally
plentiful and dicts grow more than they shrink. Python has so
many memory inefficiencies that occasional tombstones in the dict
internal structure is unlikely to be a major effect. If you're
really concerned, do `d = dict(d)` after aggressive deletion.
LtWorf wrote 2 hours 2 min ago:
Does your code actually rely on that? I've never once needed
it.
zahlman wrote 3 hours 50 min ago:
> Ordering, like stability in sorting, is an incredibly useful
property.
I can't say I've noticed any good reasons to rely on it. Didn't
reach for `OrderedDict` often back in the day either. I've had
more use for actual sorting than for preserving the insertion
order.
mcherm wrote 23 min ago:
Personally, I find lots of reasons to prefer an orders Dict
to an unordered one. Even small effects like "the debugging
output will appear in a consistent order making it easier to
compare" can be motivation enough in many use cases.
mvanbaak wrote 4 hours 53 min ago:
This was 19 (almost) 20 years ago.
As stated in the lwn.net article, a lot of concurrency has been added
to python, and it might now be time for something like a frozendict.
Things that were not useful in 2006 might be totally useful in 2026
;P
Still, like you, I'm curious wether he has anything to say about it.
aewens wrote 4 hours 20 min ago:
I think Raymond Hettinger is called out specially here because he
did a well known talk called [Modern Dictionaries]( [1] ) where
around 32:00 to 35:00 in he makes the quip about how younger
developers think they need new data structures to handle new
problems, but eventually just end up recreating / rediscovering
solutions from the 1960s.
âWhat has been is what will be, and what has been done is what
will be done; there is nothing new under the sun.â
(HTM) [1]: https://youtu.be/p33CVV29OG8
sesm wrote 4 hours 0 min ago:
Since that time HAMT was invented and successfully used in Scala
and Clojure, so this talk didn't age well.
Someone wrote 3 hours 21 min ago:
Wikipedia ( [1] ) links to the paper describing HAMT ( [2] )
and claims that is from 2000. That talk is from 2016.
(HTM) [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
(HTM) [2]: https://infoscience.epfl.ch/server/api/core/bitstreams...
ndr wrote 2 hours 55 min ago:
HAMT weren't immutable/persistent until Clojure though.
If memory serves that happened 2007-2008, so still well
before the talk.
sundarurfriend wrote 5 hours 46 min ago:
Can someone ELI5 the core difference between this and named tuples, for
someone who is not deep into Python? ChatGPT's answer boiled down to:
unordered (this) vs ordered (NTs), "arbitrary keys, decided at runtime"
vs "fixed set of fields decided at definition time" (can't an NT's keys
also be interpolated from runtime values?), and a different API
(`.keys()`, `.items()`), etc (I'm just giving this as context btw, no
idea if there's inaccuracies in these).
So could this also have been approached from the other side, as in
making unordered NamedTuples with support for the Mapping API? The line
between dictionaries and named tuples and structs (across various
languages) has always seemed a bit blurry to me, so I'm trying to get a
better picture of it all through this.
willvarfar wrote 5 hours 5 min ago:
The values in tuples cannot change. The values that keys point to in
a frozen dict can?
But yeah I'd be in favour of something that looked a lot like a named
tuple but with mutable values and supporting [name] access too. And
of course some nice syntactic sugar rather like dicts and sets have
with curly brackets today.
pansa2 wrote 4 hours 59 min ago:
> The values in tuples cannot change. The values that keys point to
in a frozen dict can?
The entries of a tuple cannot be assigned to, but the values can be
mutated. The same is true for a `frozendict` (according to the PEP
they don't support `__setitem__`, but "values can be mutable").
vscode-rest wrote 4 hours 17 min ago:
Tuple entries must be hashable, which (as far as standard library
is concerned) means immutable.
pansa2 wrote 4 hours 15 min ago:
>>> hash([1, 2])
TypeError: unhashable type: 'list'
>>> t = ([1, 2], [3, 4])
>>> print(t)
([1, 2], [3, 4])
vscode-rest wrote 4 hours 3 min ago:
Ah. Of course⦠thatâs how the workaround to use tuples as
frozen dicts can work in the first place. Slow morning for
me!
quietbritishjim wrote 5 hours 10 min ago:
> arbitrary keys, decided at runtime" vs "fixed set of fields decided
at definition time" (can't an NT's keys also be interpolated from
runtime values?)
If you want to create a named tuple with arbitrary field names at
runtime then you need to create a new named tuple type before you
create the instance. That is possible, since Python is a very dynamic
language, but it's not particularly efficient and, more importantly,
just feels a bit wrong. And are you going to somehow cache the types
and reuse them if the field names match? It's all a bit of a mess
compared to just passing the entries to the frozendict type.
_flux wrote 5 hours 19 min ago:
The key difference is what the GPT outlined: tuples have order for
the fields and named tuples are not indexed by the name, but instead
a field accessor is used, i.e. foo.bar vs foo["bar"]. In addition
namedtuples can be indexed using that order like tuples can (foo[0]),
which clearly isn't possible with dicts and would be quite confusing
if dict had integer key.
So I think the differences aren't great, but they are sufficient. A
frozendict is not going to be indexable by an integer. Python already
has an abstract type for this, for mostly the use of type checking I
imagine: [1] Documentation for namedtuple:
(HTM) [1]: https://docs.python.org/3/glossary.html#term-mapping
(HTM) [2]: https://docs.python.org/3/library/collections.html#collectio...
grimgrin wrote 5 hours 41 min ago:
I think you could have asked this same comment w/o mentioning ChatGPT
and you wouldn't have been downvoted to oblivion in 3 minutes
I don't see anything wrong with your asking to understand
chistev wrote 5 hours 3 min ago:
This place hates ChatGPT and AI. Lol.
Edit: Of course, I get down voted as I predicted I would. Lol.
acdha wrote 4 hours 59 min ago:
This place hates laziness and imprecision. Using ChatGPT for
editing or inspiration is okay as long as you personally review
the results for accuracy and completeness, at which point people
care about it as much as you announcing that you used a spell
checker.
delaminator wrote 4 hours 55 min ago:
Pasting chat GPT responses is against the site rules.
always has been even before GPT
(HTM) [1]: https://news.ycombinator.com/item?id=46206457
acdha wrote 4 hours 48 min ago:
Fair, because theyâre not your words. Iâll edit my
comment for what I had in mind: that it can be helpful for
that like a spell checker - for example, I know non-native
English speakers who find them useful for editing but they
completely understand the topic intellectually.
drhagen wrote 6 hours 14 min ago:
Great! Now make `set` have a stable order and we're done here.
cr125rider wrote 5 hours 53 min ago:
Arenât sets unsorted by definition? Or do repeated accesses without
modification yield different results?
adrian_b wrote 4 hours 27 min ago:
Not related to Python, but one of the possible implementations of a
set, i.e. of an equivalence class on sequences, is as a sorted
array (with duplicates eliminated, unless it is a multiset, where
non-unique elements are allowed in the sorted array), as opposed to
the unsorted array that can store an arbitrary sequence.
So sets can be viewed as implicitly sorted, which is why the order
of the elements cannot be used to differentiate two sets.
Being sorted internally to enforce the equivalence between sets
with elements provided in different orders does not imply anything
about the existence of an operation that would retrieve elements in
a desired order or which would return subsets less or greater than
a threshold. When such operations are desired, an order relation
must be externally defined on the set.
So a possible definition of sets and multisets is as sorted arrays
with or without unicity of elements, while sequences are unsorted
arrays (which may also have the constraint of unique elements).
However the standard set operations do not provide external access
to the internal order, which is an order between arbitrary
identifiers attached to the elements of the set, which have no
meaning externally.
Retr0id wrote 4 hours 53 min ago:
A stable order does not imply sorted order. If you convert the same
set to a list twice you'll probably get the same order both times
but it isn't guaranteed anywhere, and that order may change between
python implementations and versions. The order may also change as
the set grows or shrinks.
ledauphin wrote 4 hours 55 min ago:
this is likely in reference to the fact that dicts have maintained
insertion order since Python ~3.6 as property of the language.
Mathematically there's no defined order to a set, and a dict is
really just a set in disguise, but it's very convenient for
determinism to "add" this invariant to the language.
zahlman wrote 4 hours 24 min ago:
Sets use a different implementation intentionally (i.e. they are
not "a dict without values") exactly because it's expected that
they have different use cases (e.g. union/intersection
operations).
jonathaneunice wrote 4 hours 42 min ago:
Debugging is a completely different and better animal when
collections have a predictable ordering. Else, every dict needs
ordering before printing, studying, or comparing. Needlessly
onerous, even if philosophically justifiable.
sltkr wrote 4 hours 57 min ago:
So are dictionary keys, but Python decided to make them insertion
ordered (after having them be unordered just like set elements for
decades). There is no fundamental reason sets couldn't have a
defined order. That's what languages like JavaScript have done too.
cpburns2009 wrote 4 hours 18 min ago:
Python's decision to make dict keys ordered in the spec was a
mistake. It may be the best implementation so far, but it
eliminates potential improvements in the future.
mrweasel wrote 3 hours 11 min ago:
Agreed. The only reason to make them sorted is because people
would wrongly assume that they where. You can argue that a
programming language should not have unexpected behaviors, and
apparently unsorted dictionary keys where a surprise to many,
on the other hand I feel like it's a failure of education.
The problem was that assuming that keys would be sorted was
frequently true, but not guaranteed. An alternative solution
would have been to randomize them more, but that would probably
break a lot of old code. Sorting the keys makes no difference
if you don't expect them to be, but it will now be a greater
surprise if you switch language.
drhagen wrote 6 hours 17 min ago:
If this gets wide enough use, they could add an optimization for code
like this:
n = 1000
a = {}
for i in range(n):
a[i] = str(i)
a = frozendict(a) # O(n) operation can be turned to O(1)
It is relatively easy for the JIT to detect the `frozendict`
constructor, the `dict` input, and the single reference immediately
overwritten. Not sure if this would ever be worth it.
_flux wrote 5 hours 26 min ago:
Wouldn't ref-counting CPython already know that a has a single
reference, allowing this optimization without needing any particular
smart JIT?
zahlman wrote 4 hours 26 min ago:
First thought: I would very much expect it to be able to do this
optimization given the similar things it does for string
concatenation.
But actually, I suspect it can't do this optimization simply
because the name `frozendict` could be shadowed.
zbentley wrote 4 hours 32 min ago:
I think GP was talking about optimizing away the O(N) call on the
last line. The GC will take care of removing the reference to the
old (mutable) dict, but constructing a new frozendict from a
mutable dict would, in the current proposal, be an O(N) shallow
copy.
There are also potentially other optimizations that could be
applied (not specific to dict/frozendict) to reduce the memory
overhead on operations like "a = f(a)" for selected values of "f".
polyrand wrote 6 hours 26 min ago:
A frozen dictionary would be very welcome. You can already do something
similar using MappingProxyType [0]
from types import MappingProxyType
d = {}
d["a"] = 1
d["b"] = 2
print(d)
frozen = MappingProxyType(d)
print(frozen["a"])
# Error:
frozen["b"] = "new"
[0]:
(HTM) [1]: https://docs.python.org/3/library/types.html#types.MappingProx...
zahlman wrote 4 hours 32 min ago:
> You can already do something similar
Only if you deny access to the underlying real dict.
ali_m wrote 4 hours 6 min ago:
Yes, this only prevents the callee from mutating it, it can't
provide a strong guarantee that the underlying mapping won't be
changed upstream (and hence MappingProxyType can't be washable).
code_biologist wrote 6 hours 39 min ago:
Shoutout to pyrsistent, a personal favorite library for
frozen/immutable/hashable data structures whenever I need to use lists,
sets, or dicts as dict keys, or make sets of such items:
(HTM) [1]: https://github.com/tobgu/pyrsistent
codethief wrote 6 hours 42 min ago:
Next step: Auto-inferring the correct (most narrow) TypedDict type from
a frozendict. (Think `const foo = { ⦠} as const` in TypeScript.) I
miss this TS feature in Python on the daily.
anentropic wrote 5 hours 16 min ago:
Agreed... but it shouldn't need a frozendict for this
IMHO TypedDict in Python are essentially broken/useless as is
What is needed is TS style structural matching, like a Protocol for
dicts
mrweasel wrote 5 hours 56 min ago:
What would that do exactly? Auto-generate a TypedDict class?
Bringing up TypedDict is sort of interesting, because it seems like a
frozen dictionary could have been implemented by PEP 705, if
typing.ReadOnly was enforced at runtime, and not just a hint to a
static type checker.
dmurray wrote 5 hours 44 min ago:
Auto-generate a TypedDict type while type checking, while doing
nothing at runtime.
I expect this is not a very big ask and the various typecheckers
will have versions of this soon after release.
mrweasel wrote 5 hours 30 min ago:
Okay so basically just "inline":
class MyType(TypedDict):
a: str
b: int
or infer the type hint in:
my_typed_dict: dict[str, int] = {"a": 5}
It should probably be something like:
auto_typed: dict[typing.Const, typing.Const] = {"a": 5}
where typing.Const defaults to Any for an empty dict.
adzm wrote 6 hours 3 min ago:
Curious what this means for typescript as well; honestly I've only
reached for as const rarely.
virtue3 wrote 6 hours 27 min ago:
I also SUPER LOVE this feature. Especially when you make a type
union of the keys for easier indexing.
tweakimp wrote 6 hours 31 min ago:
Can you give a Python example of a use case for this?
(DIR) <- back to front page