我有一个数据结构,基本上相当于嵌套字典.让我们说它看起来像这样:
{'new jersey': {'mercer county': {'plumbers': 3,
'programmers': 81},
'middlesex county': {'programmers': 81,
'salesmen': 62}},
'new york': {'queens county': {'plumbers': 9,
'salesmen': 36}}}
Run Code Online (Sandbox Code Playgroud)
现在,保持和创造这个是非常痛苦的; 每当我有一个新的州/县/专业时,我必须通过令人讨厌的try/catch块创建下层词典.而且,如果我想要遍历所有值,我必须创建恼人的嵌套迭代器.
我也可以使用元组作为键,如下:
{('new jersey', 'mercer county', 'plumbers'): 3,
('new jersey', 'mercer county', 'programmers'): 81,
('new jersey', 'middlesex county', 'programmers'): 81,
('new jersey', 'middlesex county', 'salesmen'): 62,
('new york', 'queens county', 'plumbers'): 9,
('new york', 'queens county', 'salesmen'): 36}
Run Code Online (Sandbox Code Playgroud)
这使得迭代值非常简单和自然,但是做聚合和查看字典的子集(例如,如果我只想逐个状态)这样做更具语法上的痛苦.
基本上,有时我想将嵌套字典视为平面字典,有时我想将其视为复杂的层次结构.我可以把它全部包装在一个类中,但似乎有人可能已经完成了这个.或者,似乎可能有一些非常优雅的语法结构来做到这一点.
我怎么能做得更好?
附录:我知道setdefault()但它并没有真正实现干净的语法.此外,您创建的每个子词典仍需要setdefault()手动设置.
感谢SO的一些优秀人员,我发现了collections.defaultdict可见性和速度提供的可能性.我已经把它们用于成功.
现在我想实现三个级别的词典,两个顶级词典defaultdict和最低词典int.我找不到合适的方法来做到这一点.这是我的尝试:
from collections import defaultdict
d = defaultdict(defaultdict)
a = [("key1", {"a1":22, "a2":33}),
("key2", {"a1":32, "a2":55}),
("key3", {"a1":43, "a2":44})]
for i in a:
d[i[0]] = i[1]
Run Code Online (Sandbox Code Playgroud)
现在这可行,但以下,这是所需的行为,不会:
d["key4"]["a1"] + 1
Run Code Online (Sandbox Code Playgroud)
我怀疑我应该声明第二级defaultdict是类型的int,但我没有找到在哪里或如何这样做.
我defaultdict首先使用的原因是避免为每个新密钥初始化字典.
还有更优雅的建议吗?
谢谢pythoneers!
有没有办法使defaultdict也成为defaultdict的默认值?(即无限级递归defaultdict?)
我希望能够做到:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Run Code Online (Sandbox Code Playgroud)
所以,我可以这样做x = defaultdict(defaultdict),但那只是第二级:
x[0]
{}
x[0][0]
KeyError: 0
Run Code Online (Sandbox Code Playgroud)
有些食谱可以做到这一点.但是它可以简单地使用普通的defaultdict参数吗?
注意这是在询问如何进行无限级别的递归defaultdict,所以它与Python不同:defaultdict的defaultdict?,这是如何做一个两级默认.
我可能最终会使用束模式,但当我意识到我不知道如何做到这一点时,它让我感兴趣.
使用这样的回答,我创建了一个defaultdict的defaultdict秒.现在,我想把那个深层嵌套的dict对象变回普通的python dict.
from collections import defaultdict
factory = lambda: defaultdict(factory)
defdict = factory()
defdict['one']['two']['three']['four'] = 5
# defaultdict(<function <lambda> at 0x10886f0c8>, {
# 'one': defaultdict(<function <lambda> at 0x10886f0c8>, {
# 'two': defaultdict(<function <lambda> at 0x10886f0c8>, {
# 'three': defaultdict(<function <lambda> at 0x10886f0c8>, {
# 'four': 5})})})})
Run Code Online (Sandbox Code Playgroud)
我认为这不是正确的解决方案:
import json
regdict = json.loads(json.dumps(defdict))
# {u'one': {u'two': {u'three': {u'four': 5}}}}
Run Code Online (Sandbox Code Playgroud)
此外,这个答案是不充分的,因为它没有递归嵌套的字典.
我正在创建一个深层次的字典结构.我正在尝试做类似以下的事情:
dict = {}
dict['a']['b'] = True
Run Code Online (Sandbox Code Playgroud)
目前上述失败是因为密钥'a'不存在.目前,我必须检查每个嵌套级别并手动插入一个空字典.是否有某种类型的语法糖能够做到像上面这样可以产生的东西:
{'a': {'b': True}}
Run Code Online (Sandbox Code Playgroud)
无需在每个嵌套级别创建一个空字典?
我想嵌套任意数量的默认值,如下所示:
from collections import defaultdict
D = defaultdict( lambda:defaultdict(int) )
Run Code Online (Sandbox Code Playgroud)
这工作正常,如前所述.
现在我正在寻找以任意深度执行此操作的方式/函数:例如,我想要一个函数
def Gen_DDict( dim=3 ):
"code I'm looking for"
Run Code Online (Sandbox Code Playgroud)
这将为dim = 3返回:
defaultdict( lambda : defaultdict( lambda : defaultdict(int) ) )
Run Code Online (Sandbox Code Playgroud) 我想创建一个默认字典,默认值为负无穷大.我尝试过,defaultdict(float("-inf"))但它不起作用.我该怎么做呢?
python ×7
dictionary ×3
defaultdict ×2
collections ×1
mapping ×1
nested ×1
python-2.7 ×1
recursion ×1