python - PYTHON - 对字典列表进行分组
问题描述
有没有一种简单的方法在 Python3 中按键对 dict 列表进行分组我有一个复杂的输入列表,我想格式化
我的输入对象是这样的:
my_input = [
{
'name': 'nameA',
'departments': [
{
'name': 'dep1',
'details': [
{
'name': 'name_detA',
'tech_name': 'techNameA',
'others': None,
'sub_details': []
},
{
'name': 'name_detB',
'tech_name': 'techNameB',
'others': 22,
'sub_details': [
{
'id': 'idB',
'column2': 'ZZ',
'column3': 'CCC',
'column4': {
'id': 'id2',
'subColumn1': 'HHH',
'subColumn1': 'PPPP',
'subColumn1': 'FFFFFF'
}
}
]
},
{
'name': 'name_detB',
'tech_name': 'techNameB',
'others': 22,
'sub_details': [
{
'id': 'idA',
'column2': 'AA',
'column3': 'BBB',
'column4': {
'id': 'id1',
'subColumn1': 'XXXX',
'subColumn1': 'YYYYY',
'subColumn1': 'DDDDDD'
}
}
]
}
]
}
]
}
]
我的目标是将具有相同元素的元素分组details['techName']
为一个元素并合并它们sub_details
预期输出:
my_output = [
{
"name": "nameA",
"departments": [
{
"name": "dep1",
"details": [
{
"name": "name_detA",
"tech_name": "techNameA",
"others": None,
"sub_details": []
},
{
"name": "name_detB",
"tech_name": "techNameB",
"others": 22,
"sub_details": [
{
"id": "idB",
"column2": "ZZ",
"column3": "CCC",
"column4": {
"id": "id2",
"subColumn1": "HHH",
"subColumn1": "PPPP",
"subColumn1": "FFFFFF"
}
},
{
"id": "idA",
"column2": "AA",
"column3": "BBB",
"column4": {
"id": "id1",
"subColumn1": "XXXX",
"subColumn1": "YYYYY",
"subColumn1": "DDDDDD"
}
}
]
}
]
}
]
}
]
我试过了:
result_list = []
sub = []
for elem in my_input:
for data in elem["departments"]:
for sub_detail, dicts_for_that_sub in itertools.groupby(data["details"], key=operator.itemgetter("sub_details")):
sub.append({"sub_details": sub_detail})
print(sub)
但我正在努力创建新的输出
解决方案
假设我在这里使用的输入是您真正想要的,那么您就在正确的轨道上。我将最里面的 for 循环重新实现为对方法的调用,但这并不是严格需要的。
merge_details()
我可能会对usingsetdefault()
而不是if
/的方法采取稍微不同的方法,else
但如果您以前没有使用过,这种方法更容易遵循setdefault()
。
这import json
只是为了打印做一些“不错”的事情,并且不需要作为解决方案的一部分。
import json
my_input = [
{
"name": "nameA",
"departments": [
{
"name": "dep1",
"details": [
{
"name": "name_detB",
"tech_name": "techNameB",
"others": 22,
"sub_details": [
{
"id": "idB",
"column2": "ZZ",
"column3": "CCC",
"column4": {
"id": "id2",
"subColumn1": "HHH",
"subColumn2": "PPPP",
"subColumn3": "FFFFFF"
}
}
]
},
{
"name": "name_detA",
"tech_name": "techNameA",
"others": None,
"sub_details": []
},
{
"name": "name_detB",
"tech_name": "techNameB",
"others": 22,
"sub_details": [
{
"id": "idA",
"column2": "AA",
"column3": "BBB",
"column4": {
"id": "id1",
"subColumn1": "XXXX",
"subColumn2": "YYYYY",
"subColumn3": "DDDDDD"
}
}
]
}
]
}
]
}
]
def merge_details(details):
## --------------------
## dict to hold details by key (tech_name)
keyed_details = {}
## --------------------
## --------------------
## for each each "detail" if we find it in the key_detail merge the
## sub_details lists otherwise add it as the value of the key
## --------------------
for detail in details:
key = detail["tech_name"]
if keyed_details.get(key):
keyed_details[key]["sub_details"].extend(detail["sub_details"])
else:
keyed_details[key] = detail
## --------------------
return list(keyed_details.values())
for elem in my_input:
for department in elem["departments"]:
department["details"] = merge_details(department["details"])
print(json.dumps(my_input, indent=4, sort_keys=True))
推荐阅读
- javascript - 根据字段的值获取对象的最后一次出现
- c - 如何使用包含数组和字符串的代码?
- r - 在R中的多个地块之间画线
- c - 良好实践:非变异函数何时应该请求指针而不是副本?
- c# - Wix Installer 的自定义操作未创建文件夹
- python - 如何更改 andrej carpathys char rnn 以使用非文本数据类型
- html - 如何使用 CSS 将字体缩放到视口,同时保持两列布局?
- aws-lambda - 如何在 org.kie.internal.io.ResourceFactory.newFileResource 修复“java.lang.NullPointerException”
- javascript - 列表未在 v-for 指令中呈现
- dart - 如何获取用户输入作为另一个屏幕的 URL?