10

我觉得我最近看到了一种方法。假设我有一个空字典,我想在该空字典内的嵌套字典中设置一个值,但显然该嵌套字典尚未创建。是否有一种单行方式来创建中间键?这就是我想要做的:

mydict = {}
mydict['foo']['bar']['foobar'] = 25

如果您执行此代码,您将获得 'foo' 的 KeyError 异常。是否有创建中间键的功能?

谢谢。

4

3 回答 3

19
from collections import defaultdict
recursivedict = lambda: defaultdict(recursivedict)
mydict = recursivedict()

当你访问mydict['foo']时,它设置mydict['foo']为另一个recursivedict。它实际上也会构造一个recursivedictfor mydict['foo']['bar']['foobar'],但随后将它分配给25.

于 2012-04-18T21:45:20.943 回答
4

另一种选择 - 根据您的用途,是使用元组作为键而不是嵌套字典:

mydict = {}
mydict['foo', 'bar', 'foobar'] = 25

除非您想在任何时候获得树的分支(在这种情况下您无法获得 mydict['foo']),否则这将非常有效。

如果你知道你想要多少层嵌套,你也可以用functools.partiallambda 代替。

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

尽管与往常一样,在您知道存在瓶颈之前进行优化是没有意义的,所以在最快的之前选择最有用和可读的。

于 2012-04-18T21:57:02.047 回答
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}})})
于 2012-04-18T21:48:02.737 回答