Python 设置嵌套的dict值并创建中间键

Python 设置嵌套的dict值并创建中间键,python,dictionary,Python,Dictionary,我觉得我最近看到了一种方法。假设我有一个空的dict,我想在该空dict中的嵌套dict中设置一个值,但显然,嵌套dict还没有创建。是否有一种单线方式来创建中间键?这就是我想做的: mydict = {} mydict['foo']['bar']['foobar'] = 25 如果执行此代码,您将获得“foo”的KeyError异常。是否有创建中间键的功能 谢谢 from collections import defaultdict recursivedict = lambda: defau

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

mydict = {}
mydict['foo']['bar']['foobar'] = 25
如果执行此代码,您将获得“foo”的KeyError异常。是否有创建中间键的功能

谢谢

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

当您访问
mydict['foo']
时,它将
mydict['foo']
设置为另一个
recursivedict
。实际上,它也会为mydict['foo']['bar']['foobar']构造一个
递归dict
,但是如果将其分配给
25

,它就会被抛出,但不确定您为什么要这样做,但是:

>>> 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}})})
>>从集合导入defaultdict作为dd
>>>mydict=dd(lambda:dd(lambda:{}))
>>>mydict['foo']['bar']['foobar']=25
>>>麦迪克特
defaultdict(,{'foo':defaultdict(,{'bar':{'foobar':25}})

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

mydict = {}
mydict['foo', 'bar', 'foobar'] = 25
这将非常有效,除非您希望在任何时候获得树的分支(在本例中,您无法获得mydict['foo'])

如果知道需要多少层嵌套,也可以使用而不是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

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

这正是我记得读过的内容——谢谢。这可能会打破mydict['foo']=15⏎ mydict['foo']['bar']['foobar']=25。在一个大的代码库中,OP记不起他之前分配了什么值。@itsno这是真的。我不认为有什么好办法可以解决这个问题;您必须在存储的元素周围设置
\uuuuuuGetItem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
返回包装,覆盖该元素的
\uuuuuuuuuuuuuuuuuuGetItem!谢谢,那就是我要找的机器人!可能的重复只允许嵌套到三层;您希望函数是递归的,就像在中一样,以便能够继续运行。@Dougal:我写这篇文章时,您的答案并没有这么说。@Dougal:如果OP只需要三层深度,那就足够了。@StevenRumbalski…显然,是的,但考虑到OP只询问“嵌套的dict”,这是一种奇怪的要求。是的,MattH,我在你回答的时候编辑了我的答案;我的帖子旨在指出你答案的一个缺点,而不是说“我已经发布了一个更好的答案,你这个笨蛋。”:p这个解决方案没有错,但我可能需要深入到3个层次以上,所以Dougal的答案更好。谢谢有趣的东西。我从没想过用元组作为dict键。虽然这对我的情况没有帮助,但它确实有用——谢谢!当然,可以使用基于元组的解决方案通过
prefix=('foo','bar')之类的方式获得树分支;l=len(前缀);branch={k[l::]:v代表k,v在mydict.items()中,如果k[:l]==prefix}
——尽管这需要在所有键上迭代。@Dougal是的,在这一点上,您最好只使用嵌套的
dict
s。@Lattyware呃,这取决于具体情况。通常是的,但是如果您需要进行大量的深度元素访问,并且很少需要进行分支,那么使用元组方法可能会更快(因为每个访问只进行一次dict散列)。我觉得在OP的例子中,这并不是一个真正的考虑因素,尽管如此。@Dougal我最近确实看到了[一个问题](stackoverflow.com/questions/10182841/python中的二维与一维字典效率),这让我感到惊讶,似乎嵌套dict实际上比元组的访问速度更快。