【问题标题】:Creating a nested dictionary from list of lists从列表列表创建嵌套字典
【发布时间】:2020-10-22 19:24:29
【问题描述】:

我正在尝试将下面的列表列表转换为具有"epc_hlx" 键值为list of dictionary 的嵌套字典,因为它可以包含多个这样的字典元素:

      "epc_hlx":[
           {
              "measure":{
              }
           },
           {
              "measure":{
              }
           }
       ]

列表:

lst =[['header', 'aircraft'],
['header', 'engine_1'],
['header', 'engine_2'],
['header', 'engine_1', 'epc_hlx'],
['header', 'engine_1', 'epc_hlx', 'measure'],
['header', 'engine_2', 'epc_hlx'],
['header', 'engine_2', 'epc_hlx', 'measure']]

这是预期输出:

{
   "header":{
       "aircraft":{
       },
       "engine1":{
          "epc_hlx":[
               {
                  "measure":{
                  }
               }
           ]
       },
       "engine2":{
          "epc_hlx":[
               {
                  "measure":{
                  }
               }
           ]
       }
    }
}

我已经尝试了一些东西,但没有什么能达到我想要的效果。所以我坚持这个。提前感谢您的帮助

【问题讨论】:

  • 为什么 epc_hlx 映射到一个列表?
  • 因为我会有几个块 {"measure":{},"ts":{}}
  • 哦,我明白了。我没有看到你的问题中提到的,是吗?
  • 为什么epc_hlx 将列表作为值,所有其他的都有字典?有什么具体原因吗?
  • 是的,因为epc_hlx 将包含 8 个这样的字典:{"measure":{},"ts":{}}

标签: python dictionary


【解决方案1】:

我不知道这是否完全回答了您的问题。但它会给你一个想法。您可以优化解决方案。

li = [['header', 'aircraft'],
['header', 'engine_1'],
['header', 'engine_2'],
['header', 'engine_1', 'epc_hlx'],
['header', 'engine_1', 'epc_hlx', 'measure'],
['header', 'engine_1', 'epc_hlx', 'ts'],
['header', 'engine_2', 'epc_hlx'],
['header', 'engine_2', 'epc_hlx', 'measure'],
['header', 'engine_2', 'epc_hlx', 'ts']]

  1. 将所有 None 值作为字符串。 (我需要一个包含 None 的列表以使其长度相等,这就是使用 pandas 数据框的原因)

df = pd.DataFrame(li)
df[2] = df[2].astype(str)
df[3] = df[3].astype(str)

lst = df.values 

借Steven's answer

d = {}

for path in lst:
    current_level = d
    for part in path:
        if part not in current_level:
            current_level[part] = {}
        current_level = current_level[part]

输出:

d:

{'header': {'aircraft': {'None': {'None': {}}},
  'engine_1': {'None': {'None': {}},
   'epc_hlx': {'None': {}, 'measure': {}, 'ts': {}}},
  'engine_2': {'None': {'None': {}},
   'epc_hlx': {'None': {}, 'measure': {}, 'ts': {}}}}}

使用正则表达式清理'None': {}:

reg = re.compile("'None': {}")

s = str(d)
while (len(re.findall("'None': {}", s))):
    s = re.sub("'None': {}", '', s)
    
s = re.sub("{,", '{', s)

import ast
ast.literal_eval(s)  

{'header': {'aircraft': {},
  'engine_1': {'epc_hlx': {'measure': {}, 'ts': {}}},
  'engine_2': {'epc_hlx': {'measure': {}, 'ts': {}}}}}

【讨论】:

  • 非常感谢我会这样搜索,如果我成功我会接受你的回答:)
  • 您只需添加epc_hlx":[ {...} ]的逻辑即可。
  • 是的,我认为这是正确的方法,我要去吃午饭,之后我会试试的!
  • 我没有结束这个问题。我无法删除 cmets。不过,我确实撤销了你违背我的建议的企图。如果有几个用户认为他们粗鲁,那么 cmets 会被选出的版主(我不是)删除。获得答案,即使是对您有帮助的技术上正确的答案,也不是好问题的证明,许多用户都渴望因牢记规则而树立声誉。至少有 5 人不同意您认为您知道如何提出好问题的观点。如果其中三个具有某些特权,则您的问题将被关闭,直到得到改进。
  • 描述所尝试的内容将是一个很好的编辑,更好的是详细说明它究竟是如何失败的。但是请避免外部链接。用户直接喜欢帖子中的信息。
【解决方案2】:

感谢发布之前答案的 Pygirl,我终于找到了解决方案。

首先要做的是将我的输入列表修改为:

allblocs=[['header', 'aircraft'],
          ['header', 'engine_1', 'epc_hlx', 'measure'],
          ['header', 'engine_2', 'epc_hlx', 'measure']]

然后我重用了https://stackoverflow.com/a/7654004/6660373 并为epc_hlx 键添加了一个逻辑,它给了我这个代码:

dict_header={}    
for blocs in allblocs :
    current_lvl=dict_header
    for bloc in blocs : 
        if bloc not in current_lvl:
           if(bloc == "epc_hlx"):
               current_lvl[bloc]=[]
               current_lvl=current_lvl[bloc]
           elif(bloc == "measure"):
               dict_tmp={}
               dict_tmp[bloc]={}
               current_lvl.append(dict_tmp)
           else:
               current_lvl[bloc]={}
               current_lvl=current_lvl[bloc]
        else:
               current_lvl=current_lvl[bloc]

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2021-04-19
    • 2018-01-16
    • 1970-01-01
    • 2021-04-04
    相关资源
    最近更新 更多