【问题标题】:How do I create a nested format json from the list of dicts?如何从字典列表中创建嵌套格式 json?
【发布时间】:2021-02-08 01:29:11
【问题描述】:

在字典列表中创建字典

How do I group this list of dicts by the same month?。试图从这个链接实现答案,但没有运气。将不胜感激。

这是字典格式列表,我有

[
{'date':'2020-02-02','id' : '1','dept': '20020','CNT' : '1','rep_level' : 'form1'},
{'date':'2020-02-02','id' : '1','dept': '20020','CNT' : '0','rep_level' : 'form2'},
{'date':'2020-02-02','id' : '1','dept': '20020','CNT' : '4','rep_level' : 'form3'},
{'date':'2020-02-02','id' : '2','dept': '20020','CNT' : '9','rep_level' : 'all'},
{'date':'2020-02-02','id' : '3','dept': '20021','CNT' : '14','rep_level' : 'all'},
{'date':'2020-02-02','id' : '1','dept': '20022','CNT' : '5','rep_level' : 'form1'},
{'date':'2020-02-02','id' : '1','dept': '20022','CNT' : '2','rep_level' : 'form2'},
{'date':'2020-02-02','id' : '1','dept': '20022','CNT' : '3','rep_level' : 'form3'}
]

答案格式:

[
{"dept":"20020", "date":"2020-02-02", "answers":[{"id":"1", "answerValue":[1,0,4]},{"id":"2", answer:9}]},
{"dept":"20021", "date":"2020-02-02", "answers":[{"id":"3", "answerValue":14}]},
{"dept":"20022", "date":"2020-02-02", "answers":[{"id":"1", "answerValue":[5,2,3]}]}
]

谢谢,

【问题讨论】:

  • 一个部门是否有两个日期?如果是这样,那将如何改变预期的结果? rep_level 从来都不重要?
  • @Grismar,列表中所有词典的日期都相同。
  • @Grismar,rep_level 不重要

标签: python python-3.x list dictionary pydictionary


【解决方案1】:

您链接的答案中提供的解决方案是正确的,但您必须以特定方式将它们放在一起以获得您所追求的结果:

from itertools import groupby

data = [
    {'date': '2020-02-02', 'id': '1', 'dept': '20020', 'CNT': '1', 'rep_level': 'form1'},
    {'date': '2020-02-02', 'id': '1', 'dept': '20020', 'CNT': '0', 'rep_level': 'form2'},
    {'date': '2020-02-02', 'id': '1', 'dept': '20020', 'CNT': '4', 'rep_level': 'form3'},
    {'date': '2020-02-02', 'id': '2', 'dept': '20020', 'CNT': '9', 'rep_level': 'all'},
    {'date': '2020-02-02', 'id': '3', 'dept': '20021', 'CNT': '14', 'rep_level': 'all'},
    {'date': '2020-02-02', 'id': '1', 'dept': '20022', 'CNT': '5', 'rep_level': 'form1'},
    {'date': '2020-02-02', 'id': '1', 'dept': '20022', 'CNT': '2', 'rep_level': 'form2'},
    {'date': '2020-02-02', 'id': '1', 'dept': '20022', 'CNT': '3', 'rep_level': 'form3'}
]

result = [{
    'dept': dept,
    'answers': [{
        'id': identifier,
        'answerValue': [int(a['CNT']) for a in answers]
    } for identifier, answers in groupby(results, key=lambda x: x['id'])]
} for dept, results in groupby(data, key=lambda x: x['dept'])]

在里面,有:

        'answerValue': [int(a['CNT']) for a in answers]

它从answers 中的'CNT' 的字符串值构造一个答案整数值列表,作为列表推导。

answers 来自它周围的表达式:

    'answers': [{
        'id': identifier,
        'answerValue': [int(a['CNT']) for a in answers]
    } for identifier, answers in groupby(results, key=lambda x: x['id'])]

这是另一个列表解析,在调用 groupby() 之后,为 identifier 的每个值和随之而来的 answers 创建一个字典,在 'id' 字段上分组 results

而那个results来自外在理解:

result = [{
    'dept': dept,
    'answers': [{
        'id': identifier,
        'answerValue': [int(a['CNT']) for a in answers]
    } for identifier, answers in groupby(results, key=lambda x: x['id'])]
} for dept, results in groupby(data, key=lambda x: x['dept'])]

这与上一个类似,将原始data 分组为'dept',并为每个部门创建一个字典,并为其分组results

如果你print(result):

[{'dept': '20020', 'answers': [{'id': '1', 'answerValue': [1, 0, 4]}, {'id': '2', 'answerValue': [9]}]}, {'dept': '20021', 'answers': [{'id': '3', 'answerValue': [14]}]}, {'dept': '20022', 'answers': [{'id': '1', 'answerValue': [5, 2, 3]}]}]

你所追求的结果是什么。如果您愿意,您当然可以添加日期,但您表示这始终是一样的。

注意:我个人认为这是做类似事情的更有用的方法:

result = {
    dept: {
        identifier: [int(a['CNT']) for a in answers]
        for identifier, answers in groupby(results, key=lambda x: x['id'])
    }
    for dept, results in groupby(data, key=lambda x: x['dept'])
}

这让你(打印时):

{'20020': {'1': [1, 0, 4], '2': [9]}, '20021': {'3': [14]}, '20022': {'1': [5, 2, 3]}}

你可以像这样访问它:

print(result['20020']['2'])  # prints "[9]"

【讨论】:

  • 感谢您的回答。对于单个值,我不希望整数在数组中。例如)我希望它是 {'20020': {'1': [1, 0, 4], '2': 9}} 而不是 {'20020': {'1': [1, 0, 4],'2':[9]}}。我可以知道我该怎么做吗?
  • 我建议不要这样做,因为您最终会编写额外的代码来检查是否找到一个列表或单个整数作为值。作为程序员,不要把这样的数据当作人来看待,而要把它当作计算机来看待。在这种情况下,这会很棘手,因为groupby 返回的对象并不能很容易地查看其中有多少项目,因为它内部是一个iter()。最简单的方法是在事后替换单个元素,但是这需要大量额外的代码才能使结果变得更糟。
猜你喜欢
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 2021-11-20
  • 2021-04-19
  • 2018-01-16
  • 1970-01-01
相关资源
最近更新 更多