クラスには、1つのパラメーターを取るコンストラクターがあります。
class C(object):
def __init__(self, v):
self.v = v
...
コードのどこかで、dictの値がキーを知っていると便利です。
新生児のデフォルト値に渡されるキーでdefaultdictを使用したい:
d = defaultdict(lambda : C(here_i_wish_the_key_to_be))
助言がありますか?
cleverとはほとんど見なされませんが、サブクラス化はあなたの友人です:
class keydefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory is None:
raise KeyError( key )
else:
ret = self[key] = self.default_factory(key)
return ret
d = keydefaultdict(C)
d[x] # returns C(x)
いいえ、ありません。
defaultdict
実装は、不足しているkey
をそのままdefault_factory
に渡すように構成できません。上記の@JochenRitzelで提案されているように、あなたの唯一の選択肢はあなた自身のdefaultdict
サブクラスを実装することです。
しかし、それは「賢い」ものではなく、または標準のライブラリソリューション(存在する場合)ほどクリーンではありません。 このようにあなたの簡潔への答え、はい/いいえの質問は明らかに「いいえ」です。
標準ライブラリにそのような頻繁に必要なツールが欠けているのは残念です。
ここではdefaultdict
は必要ないと思います。なぜdict.setdefault
方法?
>>> d = {}
>>> d.setdefault('p', C('p')).v
'p'
もちろん、それによってC
のインスタンスが多数作成されます。それが問題である場合、私はより簡単なアプローチでうまくいくと思います:
>>> d = {}
>>> if 'e' not in d: d['e'] = C('e')
私の知る限り、defaultdict
や他の代替手段よりも高速です。
[〜#〜] eta [〜#〜]in
テストの速度と、try-except句の使用との関係について:
>>> def g():
d = {}
if 'a' in d:
return d['a']
>>> timeit.timeit(g)
0.19638929363557622
>>> def f():
d = {}
try:
return d['a']
except KeyError:
return
>>> timeit.timeit(f)
0.6167065411074759
>>> def k():
d = {'a': 2}
if 'a' in d:
return d['a']
>>> timeit.timeit(k)
0.30074866358404506
>>> def p():
d = {'a': 2}
try:
return d['a']
except KeyError:
return
>>> timeit.timeit(p)
0.28588609450770264