Python:如何将嵌套dicts中的嵌套列表转换为dicts

时间:2018-02-02 01:48:50

标签: python list dictionary recursion

所以我有这个词:

di = {'Type': ['Something1'],
      'details': [{'detail': [{'category': ['Stuff1'], 'value': ['Value1']},
                              {'category': ['Stuff2'], 'value': ['Value2']},
                              {'category': ['Stuff3'], 'value': ['Value3']},
                              {'category': ['Stuff3'], 'value': ['Value3']},
                              {'category': ['Stuff4'], 'value': ['Value4']}]}],
      'timestamp': ['2018-01-22 07:10:41']}

并希望将list除了list of dicts 之外的任何list of dicts 转换为dict以外的任何{'Type': 'Something1', 'details': {'detail': [{'category': 'Stuff1', 'value': 'Value1'}, {'category': 'Stuff2', 'value': 'Value2'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff4', 'value': 'Value4'}]}, 'timestamp': '2018-01-22 07:10:41'} 最终结果将是:

list

基本上,对于任何值为单个项list的键,该值应该删除def delistdict(dicto): delisted = {} for k,v in dicto.items(): if isinstance(v, list) and len(v) == 1: delisted[k] = v[0] else: delisted[k] = delistdict(v) return {k:v if len(v) == 1 else v for k,v in delisted.items()} 组件。

我尝试使用以下递归函数但没有成功:

list

它失败了,因为它只删除了{'detail': [(...)]中的{'Type': 'Something1', 'details': {'detail': [{'category': ['Stuff1'], 'value': ['Value1']}, {'category': ['Stuff2'], 'value': ['Value2']}, {'category': ['Stuff3'], 'value': ['Value3']}, {'category': ['Stuff3'], 'value': ['Value3']}, {'category': ['Stuff4'], 'value': ['Value4']}]}, 'timestamp': '2018-01-22 07:10:41'} 的第一个实例(所以只有那个外部 [(...)] 列表)但它没有t recurse到剩余的项目。所以在运行脚本后我的结果如下所示:

value

应该发生的事情是,categorystring键中的单个值应转换为list,而不是保留为C:\ABC\1245_PQR\125\xyz\ROW20MAOSAD12\ 中的单个项目。

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:0)

你可以试试这个:

di = {'timestamp': ['2018-01-22 07:10:41'], 'Type': ['Something1'], 'details': [{'detail': [{'category': ['Stuff1'], 'value': ['Value1']}, {'category': ['Stuff2'], 'value': ['Value2']}, {'category': ['Stuff3'], 'value': ['Value3']}, {'category': ['Stuff3'], 'value': ['Value3']}, {'category': ['Stuff4'], 'value': ['Value4']}]}]}
def flatten(d):
  return {a:b[0] if len(b) == 1 and isinstance(b[0], str) else (flatten(b[0]) if len(b) == 1 and isinstance(b[0], dict) else [flatten(c) for c in b]) for a, b in d.items()}

输出:

{'timestamp': '2018-01-22 07:10:41', 'Type': 'Something1', 'details': {'detail': [{'category': 'Stuff1', 'value': 'Value1'}, {'category': 'Stuff2', 'value': 'Value2'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff4', 'value': 'Value4'}]}}

非理解解决方案:

def flatten(d):
   new_d = {}
   for a, b in d.items():
      if len(b) == 1 and isinstance(b[0], str):
          new_d[a] = b[0]
      elif len(b) == 1 and isinstance(b[0], dict):
          new_d[a] = flatten(b[0])
      else:
          temp_list = []
          for c in b:
             temp_list.append(flatten(c))
          new_d[a] = temp_list
   return new_d

输出:

{'timestamp': '2018-01-22 07:10:41', 'Type': 'Something1', 'details': {'detail': [{'category': 'Stuff1', 'value': 'Value1'}, {'category': 'Stuff2', 'value': 'Value2'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff3', 'value': 'Value3'}, {'category': 'Stuff4', 'value': 'Value4'}]}}

答案 1 :(得分:0)

我没有花时间来优化代码,但我修改了原来的功能来实现这一目的:

def delistdict(dicto):

    delisted = {}

    for k, v in dicto.items():

        if isinstance(v, list):
            lst = []
            for i in v:
                if isinstance(i, dict):
                    lst.append(delistdict(i))
                else:
                    lst.append(i)
            delisted[k] = lst[0] if len(lst) == 1 else lst
        elif isinstance(v, dict):
            delisted[k] = delistdict(v)
        else:
            delisted[k] = v

    return {k:v if len(v) == 1 else v for k,v in delisted.items()}

输出(漂亮打印):

{'Type': 'Something1',
 'details': {'detail': [{'category': 'Stuff1', 'value': 'Value1'},
                        {'category': 'Stuff2', 'value': 'Value2'},
                        {'category': 'Stuff3', 'value': 'Value3'},
                        {'category': 'Stuff3', 'value': 'Value3'},
                        {'category': 'Stuff4', 'value': 'Value4'}]},
 'timestamp': '2018-01-22 07:10:41'}

问题是你的函数假设所有list应该有len 1,否则它只返回已删除的字典,它仍然在未处理的内部嵌套list