Что было бы “замороженный dict” быть?

  • Замороженный набор является frozenset.
  • Замороженный список мог быть кортежем.
  • Что было бы замороженный dict быть? Неизменный, hashable dict.
  • Я предполагаю, что это могло быть что-то как collections.namedtuple, но это больше похоже на зафиксированные ключи dict (полузамороженный dict).не так ли?

    "frozendict" должен быть замороженным словарем, он должен иметь keys, values, get, и т.д., и поддержка in, for, и т.д.

    обновление:
    * там это: https://www.python.org/dev/peps/pep-0603

138
задан dugres 20 September 2019 в 08:03
поделиться

2 ответа

Python не имеет встроенного типа frozendict. Оказывается, это было бы полезно не слишком часто (хотя, вероятно, это было бы полезно чаще, чем frozenset ).

Наиболее частая причина, по которой нужен такой тип, - это запоминание вызовов функций для функций с неизвестными аргументами. Наиболее распространенное решение для хранения хешируемого эквивалента словаря (где значения хешируются) - это что-то вроде tuple (sorted (kwargs.iteritems ())) .

Это зависит от того, чтобы сортировка не была безумной. Python не может положительно обещать, что сортировка приведет к чему-то разумному здесь. (Но он не может обещать ничего другого, так что не переживайте слишком много.)


Вы можете легко создать какую-нибудь оболочку, которая работает как dict. Это может выглядеть примерно так:

import collections

class FrozenDict(collections.Mapping):
    """Don't forget the docstrings!!"""

    def __init__(self, *args, **kwargs):
        self._d = dict(*args, **kwargs)
        self._hash = None

    def __iter__(self):
        return iter(self._d)

    def __len__(self):
        return len(self._d)

    def __getitem__(self, key):
        return self._d[key]

    def __hash__(self):
        # It would have been simpler and maybe more obvious to 
        # use hash(tuple(sorted(self._d.iteritems()))) from this discussion
        # so far, but this solution is O(n). I don't know what kind of 
        # n we are going to run into, but sometimes it's hard to resist the 
        # urge to optimize when it will gain improved algorithmic performance.
        if self._hash is None:
            self._hash = 0
            for pair in self.iteritems():
                self._hash ^= hash(pair)
        return self._hash

Он должен отлично работать:

>>> x = FrozenDict(a=1, b=2)
>>> y = FrozenDict(a=1, b=2)
>>> x is y
False
>>> x == y
True
>>> x == {'a': 1, 'b': 2}
True
>>> d = {x: 'foo'}
>>> d[y]
'foo'
104
ответ дан 23 November 2019 в 23:29
поделиться

Предполагая, что ключи и значения словаря сами по себе неизменяемы (например, строки), тогда:

>>> d
{'forever': 'atones', 'minks': 'cards', 'overhands': 'warranted', 
 'hardhearted': 'tartly', 'gradations': 'snorkeled'}
>>> t = tuple((k, d[k]) for k in sorted(d.keys()))
>>> hash(t)
1524953596
18
ответ дан 23 November 2019 в 23:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: