A workaround for Python's missing frozen-dict type?

EDIT:

Starting from Python 3.6, dictionaries preserve the insertion order. Therefore, the workaround would vary depending on the used Python version.

For Python < 3.6 (Dictionaries do not preserve insertion order) - use frozenset, so that two sets are equal even if order is different:

>>> a = {'key1' : 'val1', 'key2' : 'val2'}
>>> b = frozenset(a.items())
>>> frozenset_restored_to_dict = dict(b)
>>> frozenset_restored_to_dict
{'key2': 'val2', 'key1': 'val1'}

Otherwise (Dictionaries preserve insertion order), use tuple. This way, the dictionary can be restored while preserving the order of items, yet, tuples with same items ordered differently will not be equal. A workaround for it would be passing the tuples to a frozenset constructor each time before a comparison is made.

>>> a = {'key1' : 'val1', 'key2' : 'val2'}
>>> b = tuple(a.items())
>>> tuple_restored_to_dict = dict(b)
>>> tuple_restored_to_dict
{'key1': 'val1', 'key2': 'val2'}

As can be seen in the code, b is a tuple, or a frozenset. Either are immutable and hashable, and can be totally restored to be a regular dictionary like a.


You can try ordered dict or look on these answers:

  • What would a "frozen dict" be?
  • Immutable dictionary, only use as a key for another dictionary
  • How to create an immutable dictionary in python?

and there is even a package on PyPI: https://pypi.python.org/pypi/frozendict

You can also simply convert dict to tuples(sorted(your_dict.items())) and then use as a hash.

UPD: as mentioned in comments, OrderedDict is unhashable. My bad, it is really should not be hashable since it is mutable.