- 凍結セットは凍結セットです。
- 凍結されたリストはタプルになる場合があります。
- 凍結された辞書とは何でしょうか? 不変でハッシュ可能な辞書です。
のようなものになると思いますcollections.namedtuple
が、これは、frozen-keys dict (半凍結された辞書) のようなものです。そうではありませんか?
「frozendict」は凍結された辞書であり、、、などを持ちkeys
、、、values
などをサポートget
する必要があります。in
for
更新:
* ここにあります: https://www.python.org/dev/peps/pep-0603
ベストアンサー1
Python には組み込みの freezedict 型がありません。これはあまり役に立たないことがわかりました (それでも、おそらく今よりは頻繁に役に立つでしょうがfrozenset
)。
このような型が必要になる最も一般的な理由は、不明な引数を持つ関数の関数呼び出しをメモ化する場合です。ハッシュ可能な辞書 (値がハッシュ可能なもの) と同等のものを格納する最も一般的なソリューションは、次のようになりますtuple(sorted(kwargs.items()))
。
これは、ソートが少しも狂っていないことに依存します。Python は、ソートがここで妥当な結果になることを積極的に保証することはできません。(ただし、他のことは保証できないので、あまり心配する必要はありません。)
辞書のように動作するラッパーを簡単に作成できます。次のようになります ( Python 3.10 以降では、collections.Mappings
を に置き換えますcollections.abc.Mappings
)。
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:
hash_ = 0
for pair in self.items():
hash_ ^= hash(pair)
self._hash = hash_
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'