【问题标题】:Nested insertion/creation of dictionary嵌套插入/创建字典
【发布时间】:2018-04-17 13:58:09
【问题描述】:

假设你有一本空字典

data = {}

我有一个路径和一个值

path = "root.sub.item"
value = 12

如何递归添加不存在的对象?

def add_value(path, value):
    for part in path.split('.'):
        if not part in data:
            data[part] = {}

预期的输出是:

data = {
    'root':{
        'sub':{
            'item': 12
        }
    }
}

有人可以帮忙解决这个问题或为我指明正确的方向吗?
我正在使用 Python 3.6。

【问题讨论】:

    标签: python python-3.x dictionary recursion defaultdict


    【解决方案1】:

    您可以使用另一种解决方案,例如递归 defaultdict,如 this answer

    一个关于如何使用它的快速而愚蠢的例子:

    from collections import defaultdict
    
    def func(rdict, path, value):
        items = path.split('.')
    
        d = rdict[items[0]]
    
        for item in items[1:-1]:
            d = d[item]
    
        d[items[-1]] = value
    
    nested_dict = lambda: defaultdict(nested_dict)
    
    result = nested_dict()
    
    func(result, 'root.sub.item', 12)
    func(result, 'root.moon.value', 1)
    
    assert result['root']['sub']['item'] == 12
    assert result['root']['moon']['value'] == 1
    assert result['root']['moon']['noop'] != 0
    

    【讨论】:

      【解决方案2】:

      你快到了,你只需要跟踪你在树结构中的距离,以及知道你何时在路径的最后一个元素上的方法:

      def add_value(path, value):
          tmp = data
          parts = list(path.split('.'))
          for i in range(len(parts) - 1):
              part = parts[i]
              if not part in tmp:
                  tmp[part] = {}
              tmp = tmp[part]
          tmp[parts[-1]] = value
      

      【讨论】:

      • 但这只会给我最后一次插入。例如。 {'item': 12} ?
      • @DennisDelin,你运行了吗?当我运行它时,我会得到 data 以及您描述的嵌套结构。
      • 是的,如果我在函数末尾打印 tmp,它只会保存最后一个值为 12 的字典
      • 对,因为tmp是一个临时变量,用于将值取入data。如果打印 data 会发生什么?
      【解决方案3】:

      你可以试试 Raymond Hettinger 的食谱:

      来源:https://twitter.com/raymondh/status/343823801278140417

      from collections import defaultdict
      
      infinity_dict=lambda:defaultdict(infinity_dict)
      
      d=infinity_dict()
      d['root']['sub']['item'] = 12
      

      【讨论】:

        猜你喜欢
        • 2023-01-18
        • 1970-01-01
        • 2021-04-04
        • 1970-01-01
        • 2018-11-09
        • 2018-03-27
        • 1970-01-01
        • 2021-06-02
        相关资源
        最近更新 更多