我觉得我最近看到了这样做的方法。假设我有一个空字典,我想在该空字典中的嵌套字典中设置一个值,但显然嵌套字典尚未创建。是否有一种创建中间键的方法?这就是我想要做的事情:
mydict = {}
mydict['foo']['bar']['foobar'] = 25
如果执行此代码,您将获得'foo'的KeyError异常。是否有创建中间键的功能?
感谢。
答案 0 :(得分:17)
from collections import defaultdict
recursivedict = lambda: defaultdict(recursivedict)
mydict = recursivedict()
当您访问mydict['foo']
时,会将mydict['foo']
设置为另一个recursivedict
。它实际上也会为recursivedict
构建一个mydict['foo']['bar']['foobar']
,但是通过将其分配给25
,它会被抛弃。
答案 1 :(得分:3)
另一种选择 - 取决于你的用途,是使用元组作为键而不是嵌套字典:
mydict = {}
mydict['foo', 'bar', 'foobar'] = 25
除非你想在任何时候获得树的一个分支(在这种情况下你不能得到mydict ['foo']),这将非常有效。
如果你知道你想要多少层嵌套,你也可以使用functools.partial
而不是lambda。
from functools import partial
from collections import defaultdict
tripledict = partial(defaultdict, partial(defaultdict, dict))
mydict = tripledict()
mydict['foo']['bar']['foobar'] = 25
有些人发现更具可读性,并且创建实例比基于lambda的等效解决方案更快:
python -m timeit -s "from functools import partial" -s "from collections import defaultdict" -s "tripledefaultdict = partial(defaultdict, partial(defaultdict, dict))" "tripledefaultdict()"
1000000 loops, best of 3: 0.281 usec per loop
python -m timeit -s "from collections import defaultdict" -s "recursivedict = lambda: defaultdict(recursivedict)" "recursivedict()"
1000000 loops, best of 3: 0.446 usec per loop
虽然一如既往,在你知道存在瓶颈之前没有优势,但在最快之前选择最有用和可读的内容。
答案 2 :(得分:0)
不确定你为什么要这样做,但是:
>>> from collections import defaultdict as dd
>>> mydict = dd(lambda: dd(lambda: {}))
>>> mydict['foo']['bar']['foobar'] = 25
>>> mydict
defaultdict(<function <lambda> at 0x021B8978>, {'foo': defaultdict(<function <lambda> at 0x021B8618>, {'bar': {'foobar': 25}})})