假设我想在Python中使用类似PERL的自动修复,即:
>>> d = Autovivifier()
>>> d = ['nested']['key']['value']=10
>>> d
{'nested': {'key': {'value': 10}}}
有几种主要方法可以做到这一点:
__missing__
hook to return the nested structure 好的 - 容易。
现在假设我想从缺少密钥的dict返回默认值。再一次,没有办法做到这一点:
__missing__
hook {}.get(key, default)
(does not easily work with a nested dict),即autoviv.get(['nested']['key']['no key of this value'], default)
这两个目标似乎是不可调和的冲突(基于我试图在过去几个小时内解决这个问题。)
以下是问题:
假设我想要一个Autivivifying dict,1)为d['arbitrary']['nested']['path']
创建嵌套结构; AND 2)从不存在的任意嵌套中返回一个默认值,而不将其包装在try / except中?
以下是问题:
d['nested']['key']['no key of this value']
is equivalent to (d['nested'])['key']['no key of this value']
的来电。如果没有返回覆盖__getitem__
的对象,则覆盖__getitem__
不起作用。if d['p1']['sp2']['etc.']
测试它,我不希望if
创建整个路径。 我如何在Python中提供一个dict:
d['p1']['p2'][etc]=val
类型的访问路径(Autovivication); {}.get(key, default)
),不包含在try / except d=['nested']['key']['value']=val
和d['nested']['key']['no key of this value']
等于默认值。我希望测试d['nested']['key']['no key of this value']
不会创建它,但会接受它。答案 0 :(得分:2)
要创建一个递归的词典树,请使用defaultdict
并使用技巧:
from collections import defaultdict
tree = lambda: defaultdict(tree)
然后,您可以使用x = tree()
创建x。
以上来自@BrenBarn - defaultdict of defaultdict, nested
答案 1 :(得分:2)
不要这样做。只需编写一个具有您想要的操作的类就可以更容易地解决它,甚至在Perl中它也不是一个普遍评估的功能。
但是,使用自定义的autoviv类, 是可能的。您需要__getitem__
返回空的autoviv dict ,但不会存储。新的autoviv dict会记住创建它的autoviv dict和key,然后只有在" real"值存储在其中。
由于空dict测试为falsey,因此您可以测试是否存在Perl样式,而无需实际创建中间dicts。
但我不会写出代码,因为我很确定这是一个糟糕的主意。
答案 2 :(得分:1)
虽然它与Python中的字典协议不完全匹配,但您可以通过实现使用变量 getitem 参数的自己的自动生成字典来获得合理的结果。类似于(2.x):
class ExampleVivifier(object):
""" Small example class to show how to use varargs in __getitem__. """
def __getitem__(self, *args):
print args
示例用法是:
>>> v = ExampleVivifier()
>>> v["nested", "dictionary", "path"]
(('nested', 'dictionary', 'path'),)
您可以填写空白,了解如何在此处实现您想要的行为。