一个类具有一个带有一个参数的构造函数:
class C(object):
def __init__(self, v):
self.v = v
...
在代码中的某处,对于字典中的值了解其键很有用。
我想使用defaultdict并将密钥传递给新生儿默认值:
d = defaultdict(lambda : C(here_i_wish_the_key_to_be))
有什么建议?
Answers:
它几乎不算聪明 -但子类化是您的朋友:
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
的__missing__()
方法(因为dict
自2.5版以来,该方法可以在内置类的任何子类中使用)。
我认为您根本不需要defaultdict
这里。为什么不只是使用dict.setdefault
方法?
>>> d = {}
>>> d.setdefault('p', C('p')).v
'p'
那当然会创建许多实例C
。万一这是一个问题,我认为更简单的方法可以做到:
>>> d = {}
>>> if 'e' not in d: d['e'] = C('e')
据defaultdict
我所知,它将比或任何其他替代方案更快。
预计到达速度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
d[key]
返回。但是您的解决方案要求他实际去预先设置好吗?他怎么知道他需要什么?d[key] = C(key)
key not in d
d[key]
key
这是一个自动添加值的字典的工作示例。在/ usr / include中查找重复文件的演示任务。请注意,定制字典PathDict仅需要四行:
class FullPaths:
def __init__(self,filename):
self.filename = filename
self.paths = set()
def record_path(self,path):
self.paths.add(path)
class PathDict(dict):
def __missing__(self, key):
ret = self[key] = FullPaths(key)
return ret
if __name__ == "__main__":
pathdict = PathDict()
for root, _, files in os.walk('/usr/include'):
for f in files:
path = os.path.join(root,f)
pathdict[f].record_path(path)
for fullpath in pathdict.values():
if len(fullpath.paths) > 1:
print("{} located in {}".format(fullpath.filename,','.join(fullpath.paths)))