【问题标题】:Reduce levels of nested dictionaries when they have one element当嵌套字典只有一个元素时减少它们的级别
【发布时间】:2021-07-23 02:01:09
【问题描述】:

当节点有 1 个元素时,我需要通过将内部键附加到上键来减少字典的嵌套级别。

例子:

鉴于这本词典:

{'A': {'a': {'1': {}}},
 'B': {'b': {'2': {}},
       'c': {'3': {'x': {}}},
       'd': {},
       'e': {'0': {},
             '1': {},
            },
       },
}

我需要返回:

{'A a 1': {},
 'B': {'b 2': {},
       'c 3 x': {},
       'd': {},
       'e': {'0': {},
             '1': {},
            },
       },
 }

它应该对任意数量的级别都是通用的,并且最后一个元素始终是一个空字典。

【问题讨论】:

    标签: python dictionary recursion data-structures nested


    【解决方案1】:

    您可以先展平结构以检索所有路径,然后使用collections.defaultdict 重建它:

    import collections
    data = {'A': {'a': {'1': {}}}, 'B': {'b': {'2': {}}, 'c': {'3': {'x': {}}}, 'd': {}, 'e': {'0': {}, '1': {}}}}
    def flatten(d, c = []):
      for a, b in d.items():
         if not b:
            yield (c+[a], b)
         else:
            yield from flatten(b, c +[a])
    
    def compress(d):
       _d, r = collections.defaultdict(list), {}
       for [a, *b], c in d:
         _d[a].append((b, c))
       for a, b in _d.items():
          val = compress(b) if len(b) > 1 and all(j for j, _ in b) else b[0][-1]
          r[a if len(b) > 1 else a+' '+' '.join(b[0][0])] = val
       return r
    
    print(compress(list(flatten(data))))
    

    输出:

    {'A a 1': {}, 
     'B': {'b 2': {}, 
           'c 3 x': {}, 
           'd ': {}, 
           'e': {'0 ': {}, 
                 '1 ': {}}
           }
     }
    

    【讨论】:

      【解决方案2】:

      我相信这个递归函数适用于您的示例:

      def flatten_keys(key_so_far = '', d={}):
          if len(d) > 1:
              sub_dict = {}
              for (k,v) in d.items():
                  sub_dict.update(flatten_keys(k, v))
              return {key_so_far: sub_dict} if key_so_far else sub_dict
          elif d == {}:
              return {key_so_far: {}}
          else:
              k,v = list(d.items())[0]
              key_so_far += (' ' if key_so_far else '') + k
              return(flatten_keys(key_so_far, v))
      
      input_d = {'A': {'a': {'1': {}}},
       'B': {'b': {'2': {}},
             'c': {'3': {'x': {}}},
             'd': {},
             'e': {'0': {},
                   '1': {},
                  },
             },
      }
      
      flatten_keys(input_d)
      
      # {'A a 1': {}, 'B': {'b 2': {}, 'c 3 x': {}, 'd': {}, 'e': {'0': {}, '1': {}}}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-30
        • 1970-01-01
        • 1970-01-01
        • 2020-06-07
        • 1970-01-01
        • 2019-01-09
        • 1970-01-01
        • 2017-11-24
        相关资源
        最近更新 更多