キーのキー値を返すpython辞書を作成したいのですが、辞書にありません。
使用例:
dic = smart_dict()
dic['a'] = 'one a'
print(dic['a'])
# >>> one a
print(dic['b'])
# >>> b
キーのキー値を返すpython辞書を作成したいのですが、辞書にありません。
使用例:
dic = smart_dict()
dic['a'] = 'one a'
print(dic['a'])
# >>> one a
print(dic['b'])
# >>> b
dict
これには次の__missing__
フックがあります。
class smart_dict(dict):
def __missing__(self, key):
return key
次のように単純化できます(self
使用されないため):
class smart_dict(dict):
@staticmethod
def __missing__(key):
return key
なぜあなただけを使用しないのですか
dic.get('b', 'b')
確かに、他の人が指摘するようにサブクラス化することはできますが、時々デフォルト値を持つことができることdict
を思い出しておくと便利です!get
を試してみたい場合は、次の方法defaultdict
を試してください。
dic = defaultdict()
dic.__missing__ = lambda key: key
dic['b'] # should set dic['b'] to 'b' and return 'b'
を除いて... まあ: AttributeError: ^collections.defaultdict^object attribute '__missing__' is read-only
、したがって、サブクラス化する必要があります:
from collections import defaultdict
class KeyDict(defaultdict):
def __missing__(self, key):
return key
d = KeyDict()
print d['b'] #prints 'b'
print d.keys() #prints []
おめでとう。あなたも標準collections.defaultdict
型の無用さを発見しました。コードの悪臭のひどい山の山
が私のものと同じくらいあなたの繊細な感性を怒らせるなら、これはあなたの幸運な StackOverflow 日です。
ビルトインの3 パラメーター バリアントの禁断の驚異のおかげで、type()
役に立たないデフォルトのディクショナリ タイプを作成することは、楽しくて有益です。
過剰な定型文と衝撃的な愚かさが好きだcollections.defaultdict
とすれば、期待どおりに動作するはずですが、実際にはそうではありません。公平を期すために、オプションの
メソッドをサブクラス化して実装するJochen Ritzelの受け入れられたソリューションは、単一のデフォルト辞書のみを必要とする小規模なユースケースの優れた回避策です。dict
__missing__()
しかし、この種のボイラープレートはスケーリングが不十分です。複数のデフォルト ディクショナリをインスタンス化し、それぞれが不足しているキーと値のペアを生成するための独自のわずかに異なるロジックを使用していることに気付いた場合は、産業用に強力な代替の自動化ボイラープレートが保証されます。
または少なくとも素晴らしい。壊れたものを修正しないのはなぜですか?
純粋な Python の 10 行未満 (docstring、コメント、および空白を除く) で、DefaultDict
不足しているキーのデフォルト値を生成するユーザー定義の callable で初期化された型を定義します。標準collections.defaultdict
型に渡された callable は無駄
にパラメーターを受け入れませんDefaultDict
が、型に渡された callable は次の 2 つのパラメーターを有効に受け入れます。
このタイプを考えると、sorinの質問を解くことは、Python の 1 行に短縮されます。
>>> dic = DefaultDict(lambda self, missing_key: missing_key)
>>> dic['a'] = 'one a'
>>> print(dic['a'])
one a
>>> print(dic['b'])
b
正気。やっと。
def DefaultDict(keygen):
'''
Sane **default dictionary** (i.e., dictionary implicitly mapping a missing
key to the value returned by a caller-defined callable passed both this
dictionary and that key).
The standard :class:`collections.defaultdict` class is sadly insane,
requiring the caller-defined callable accept *no* arguments. This
non-standard alternative requires this callable accept two arguments:
#. The current instance of this dictionary.
#. The current missing key to generate a default value for.
Parameters
----------
keygen : CallableTypes
Callable (e.g., function, lambda, method) called to generate the default
value for a "missing" (i.e., undefined) key on the first attempt to
access that key, passed first this dictionary and then this key and
returning this value. This callable should have a signature resembling:
``def keygen(self: DefaultDict, missing_key: object) -> object``.
Equivalently, this callable should have the exact same signature as that
of the optional :meth:`dict.__missing__` method.
Returns
----------
MappingType
Empty default dictionary creating missing keys via this callable.
'''
# Global variable modified below.
global _DEFAULT_DICT_ID
# Unique classname suffixed by this identifier.
default_dict_class_name = 'DefaultDict' + str(_DEFAULT_DICT_ID)
# Increment this identifier to preserve uniqueness.
_DEFAULT_DICT_ID += 1
# Dynamically generated default dictionary class specific to this callable.
default_dict_class = type(
default_dict_class_name, (dict,), {'__missing__': keygen,})
# Instantiate and return the first and only instance of this class.
return default_dict_class()
_DEFAULT_DICT_ID = 0
'''
Unique arbitrary identifier with which to uniquify the classname of the next
:func:`DefaultDict`-derived type.
'''
鍵は…わかった、鍵?この難解な魔法への呼び出しは、ビルトインの3 パラメーター バリアントへ
の呼び出しtype()
です。
type(default_dict_class_name, (dict,), {'__missing__': keygen,})
この 1 行は、オプションのメソッドを呼び出し元定義の callable にdict
エイリアスする新しいサブクラスを動的に生成します。__missing__
ボイラープレートが明確に欠けていることに注意してくださいDefaultDict
。使用量は Python の 1 行に減っています。
ひどい勝利のための自動化。
最初の回答者は について言及しましたが、 の任意のサブクラスをdefaultdict
定義できます:__missing__
dict
>>> class Dict(dict):
def __missing__(self, key):
return key
>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d['z']
'z'
また、2 番目の回答者のアプローチも気に入っています。
>>> d = dict(a=1, b=2)
>>> d.get('z', 'z')
'z'
サブクラスdict
の__getitem__
メソッド。たとえば、dict を適切にサブクラス化し、 __getitem__ と __setitem__ をオーバーライドする方法