109

クラスには、1 つのパラメーターを取るコンストラクターがあります。

class C(object):
    def __init__(self, v):
        self.v = v
        ...

コードのどこかで、dict の値がキーを知っていると便利です。
新生児のデフォルト値に渡されるキーで defaultdict を使用したい:

d = defaultdict(lambda : C(here_i_wish_the_key_to_be))

助言がありますか?

4

5 に答える 5

153

賢いとは言えませんが、サブクラス化はあなたの友達です。

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)
于 2010-05-26T11:28:08.023 に答える
33

いいえ、ありません。

実装は、設定なしで Missing を渡すように構成するdefaultdictことはできません。上記の@JochenRitzelで提案されているように、唯一のオプションは独自のサブクラスを実装することです。keydefault_factorydefaultdict

しかし、それは「賢明」ではなく、標準ライブラリ ソリューション (存在する場合) ほどクリーンでもありません。したがって、簡潔な「はい/いいえ」の質問に対する答えは、明らかに「いいえ」です。

標準ライブラリに、頻繁に必要とされるツールが欠けているのは残念です。

于 2016-01-29T19:24:43.363 に答える
7

ここにいる必要はまったくないと思いますdefaultdictdict.setdefaultメソッドだけを使用しないのはなぜですか?

>>> d = {}
>>> d.setdefault('p', C('p')).v
'p'

もちろん、それは の多くのインスタンスを作成しますC。それが問題である場合は、より単純なアプローチでうまくいくと思います:

>>> d = {}
>>> if 'e' not in d: d['e'] = C('e')

defaultdict私が見る限り、それはまたは他の代替手段よりも高速です。

テスト速度とintry-except 句の使用に関するETA :

>>> 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
于 2010-05-26T11:46:04.397 に答える