如何最佳实现嵌套字典?

228

我有一个数据结构,它基本上相当于一个嵌套的字典。假设它看起来像这样:

{'new jersey': {'mercer county': {'plumbers': 3,
                                  'programmers': 81},
                'middlesex county': {'programmers': 81,
                                     'salesmen': 62}},
 'new york': {'queens county': {'plumbers': 9,
                                'salesmen': 36}}}

现在,维护和创建这个东西相当痛苦;每次我有一个新的州/县/行业,我都必须通过令人讨厌的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}

这使得对值进行迭代非常简单和自然,但是在执行聚合操作和查看字典子集(例如,如果我只想逐个州地浏览)等操作时,语法上更加繁琐。

基本上,有时我想将嵌套的字典视为平面字典,有时我确实想将其视为复杂层次结构。我可以将所有内容包装在一个类中,但似乎已经有人做过了。或者,似乎有一些非常优雅的语法结构可以实现这一点。

我该如何更好地做到这一点?

补充说明:我知道setdefault(),但它的语法并不清晰。此外,您创建的每个子字典仍需要手动设置setdefault()

22个回答

0

我有类似的事情。我有很多情况需要这样做:

thedict = {}
for item in ('foo', 'bar', 'baz'):
  mydict = thedict.get(item, {})
  mydict = get_value_for(item)
  thedict[item] = mydict

但是如果要深入多个级别,关键在于“.get(item, {})",因为它会在没有字典的情况下创建另一个字典。同时,我一直在思考如何更好地处理这个问题。目前,还有很多

value = mydict.get('foo', {}).get('bar', {}).get('baz', 0)

所以,我做了以下内容:

def dictgetter(thedict, default, *args):
  totalargs = len(args)
  for i,arg in enumerate(args):
    if i+1 == totalargs:
      thedict = thedict.get(arg, default)
    else:
      thedict = thedict.get(arg, {})
  return thedict

如果你这样做,它会产生相同的效果:

value = dictgetter(mydict, 0, 'foo', 'bar', 'baz')

更好了吗?我觉得是的。

0
以下是从上面复制的内容,有没有一种实现追加函数的方法。我正在尝试使用嵌套字典将值存储为数组。
class Vividict(dict):
    def __missing__(self, key):
        value = self[key] = type(self)() # retain local pointer to value
    return value  

我的当前实现如下:

totalGeneHash=Vividict()
        
for keys in GenHash:
    for second in GenHash[keys]:
        if keys in sampleHash:
            total_val = GenHash[keys][second]
                totalGeneHash[gene][keys].append(total_val)
This is the error I get: AttributeError: 'Vividict' object has no attribute 'append'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接