有没有一个聪明的方法将密钥传递给defaultdict的default_factory?

一个类有一个构造函数,它带有一个参数:

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

在代码的某个地方,对于dict中的值来说,知道它们的键是很有用的。
我想使用传递给新生默认值的密钥使用defaultdict:

 d = defaultdict(lambda : C(here_i_wish_the_key_to_be)) 

有什么build议么?

它几乎没有资格作为聪明 – 但子类是你的朋友:

 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实现无法configuration为将缺less的key传递到default_factory开箱即用。 你唯一的select是实现你自己的defaultdict子类,如上面@JochenRitzel所build议的。

但是,这并不像标准的图书馆解决scheme(如果存在的话)那么“巧妙”或接近干净。 因此,对简洁的答案(是/否)显然是“不”。

标准库缺less这种经常需要的工具太糟糕了。

我不认为你在这里需要defaultdict 。 为什么不使用dict.setdefault方法?

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

那当然会创造出很多C例子。 如果这是一个问题,我认为更简单的方法将做到:

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

就我所知,它会比defaultdict或其他select更快。

ETA关于testing速度与使用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