Python 如何从dict列表中创建嵌套格式的json?

Python 如何从dict列表中创建嵌套格式的json?,python,python-3.x,list,dictionary,pydictionary,Python,Python 3.x,List,Dictionary,Pydictionary,在词典列表中创建词典 。试图实现此链接中的答案,但没有成功。非常感谢您的帮助 这是字典格式的列表,我有 [ {'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' :

在词典列表中创建词典

。试图实现此链接中的答案,但没有成功。非常感谢您的帮助

这是字典格式的列表,我有

[
{'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]}]}
]

谢谢,

您链接的答案中提供的解决方案是正确的,但您必须以特定的方式将其全部放在一起,才能得到您想要的结果:

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': [{
        'id': identifier,
        'answerValue': [int(a['CNT']) for a in answers]
    } for identifier, answers in groupby(results, key=lambda x: x['id'])]
这是另一个列表理解,在调用
groupby()
,对
'id'
字段上的
结果进行分组后,为
标识符的每个值创建一个字典,并为其附带的
答案创建一个字典

结果
来自外部理解:

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'])]
这与上一步类似,按
'dept'
对原始
数据进行分组,并为每个部门创建一个字典,并将
结果
分组

如果您
打印(结果)

这就是你想要的结果。当然,如果您愿意,您可以添加日期,但您表示无论如何这都是相同的

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

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'])
}
这会让你(打印时):

您可以这样访问:

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

您链接的答案中提供的解决方案是正确的,但您必须以特定的方式将其组合在一起,以获得您想要的结果:

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': [{
        'id': identifier,
        'answerValue': [int(a['CNT']) for a in answers]
    } for identifier, answers in groupby(results, key=lambda x: x['id'])]
这是另一个列表理解,在调用
groupby()
,对
'id'
字段上的
结果进行分组后,为
标识符的每个值创建一个字典,并为其附带的
答案创建一个字典

结果
来自外部理解:

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'])]
这与上一步类似,按
'dept'
对原始
数据进行分组,并为每个部门创建一个字典,并将
结果
分组

如果您
打印(结果)

这就是你想要的结果。当然,如果您愿意,您可以添加日期,但您表示无论如何这都是相同的

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

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'])
}
这会让你(打印时):

您可以这样访问:

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

一个部门有两次约会吗?如果是这样,这将如何改变期望的结果?
rep_级别
从来都不重要?@Grismar,列表中所有词典的日期都是相同的。@Grismar,rep_级别不重要一个部门有两个日期吗?如果是这样,这将如何改变期望的结果?
rep\u级别
从来都不重要?@Grismar,列表中所有词典的日期都是相同的。@Grismar,rep\u级别不重要谢谢你的回答。对于单值,我不希望整数在数组中。例如,我希望它是{'20020':{'1':[1,0,4],'2':9}},而不是{'20020':{'1':[1,0,4],'2':[9]}。我可以知道我该怎么做吗?我建议不要这样做,因为你最终会编写额外的代码来检查是要找到一个列表还是一个整数作为一个值。作为一名程序员,不要像人类一样看待数据,而要像计算机一样看待数据。在这种情况下,由于
groupby
返回的对象在内部是一个
iter()
,因此很难看到其中有多少项。最简单的方法是在事实发生后替换单个元素,但这需要大量额外的代码才能使结果变得更糟。谢谢你的回答。对于单值,我不希望整数在数组中。例如,我希望它是{'20020':{'1':[1,0,4],'2':9}},而不是{'20020':{'1':[1,0,4],'2':[9]}。我可以知道我该怎么做吗?我建议不要这样做,因为你最终会编写额外的代码来检查是要找到一个列表还是一个整数作为一个值。作为一名程序员,不要像人类一样看待数据,而要像计算机一样看待数据。在这种情况下,由于
groupby
返回的对象在内部是一个
iter()
,因此很难看到其中有多少项。最简单的方法是在事后替换单个元素,但这需要大量额外的代码才能使结果变得更糟。