python - 如何在 Python 中将嵌套字典中的 2 个键/值向上移动一级
问题描述
昨天我在这里重新构建一个字典列表时遇到了一个问题(我提到它可以帮助其他有类似问题的人):
但是,我省略了数据的一个(现在看起来很关键)部分。最初我认为稍后添加额外的字典键会很容易,但事实证明这在结构上很麻烦。因此,我想出了以下方法,以接近我的要求。
本质上,我希望将 2 个键 'selection_id' 和 'other_data' 上移一级并完全替换 'market_data' 字典(参见下面的理想数据结构)。
我以为我可以找到一种使用 setattr 的方法,但这似乎在循环中存在问题,使用嵌套字典。此外,我什至不确定这是一种合适的方式,因为无论如何我都会预先收到所有数据,只是格式错误。
我接近的示例代码如下所示:
market=[{'selection_id': 1099,'value':'11', 'value_name': 'a', 'other_data': 89},
{'selection_id': 1099,'value':'78', 'value_name': 'p', 'other_data': 89},
{'selection_id': 1097,'value':'39', 'value_name': 'b', 'other_data': 89},
{'selection_id': 1097,'value':'52', 'value_name': 'f', 'other_data': 89},
{'selection_id': 1098,'value':'98', 'value_name': 'd', 'other_data': 89},
{'selection_id': 1099,'value':'13', 'value_name': 'y', 'other_data': 89},
{'selection_id': 1098,'value':'4', 'value_name': 'r', 'other_data': 89},
]
new_structure = {}
new_structure2 = []
for z in market:
new_structure.setdefault((z['selection_id'], z['other_data']), []).append({'value': z['value'], 'value_name': z['value_name']})
new_structure2.append([{'market_data': m, 'value_dict': n} for m, n in new_structure.items()])
for s in new_structure2:
for t in s:
dict = {}
dict['selection_id'] = t['market_data'][0]
dict['other_data'] = t['market_data'][1]
t['market_data'] = dict
print(new_structure2)
上面的代码产生以下内容:
[[{'market_data':
{'selection_id': 1099, 'other_data': 89}, 'value_dict':
[{'value': '11', 'value_name': 'a'}, {'value': '78', 'value_name': 'p'}, {'value': '13', 'value_name': 'y'}]},
{'market_data':
{'selection_id': 1097, 'other_data': 89}, 'value_dict':
[{'value': '39', 'value_name': 'b'}, {'value': '52', 'value_name': 'f'}]}, {'market_data':
{'selection_id': 1098, 'other_data': 89}, 'value_dict':
[{'value': '98', 'value_name': 'd'}, {'value': '4', 'value_name': 'r'}]}]]
而我正在寻找的是:
[{'selection_id': 1099, 'other_data': 89, 'value_dict':
[{'value': '11', 'value_name': 'a'}, {'value': '78', 'value_name': 'p'}, {'value': '13', 'value_name': 'y'}]},
{'selection_id': 1097, 'other_data': 89, 'value_dict':
[{'value': '39', 'value_name': 'b'}, {'value': '52', 'value_name': 'f'}]},
{'selection_id': 1098, 'other_data': 89, 'value_dict':
[{'value': '98', 'value_name': 'd'}, {'value': '4', 'value_name': 'r'}]}]
为免生疑问,对于任何给定的 'selection_id','other_data' 总是相同的,即如果有 2 个 'selection_id' = 1099 的实例,那么对于这些,'other_data' 将总是等于 89(在示例中它们都是89,但实际上对于不同的 selection_id 可能会有所不同)。
解决方案
这是一种方法。
前任:
market=[{'selection_id': 1099,'value':'11', 'value_name': 'a', 'other_data': 89},
{'selection_id': 1099,'value':'78', 'value_name': 'p', 'other_data': 89},
{'selection_id': 1097,'value':'39', 'value_name': 'b', 'other_data': 89},
{'selection_id': 1097,'value':'52', 'value_name': 'f', 'other_data': 89},
{'selection_id': 1098,'value':'98', 'value_name': 'd', 'other_data': 89},
{'selection_id': 1099,'value':'13', 'value_name': 'y', 'other_data': 89},
{'selection_id': 1098,'value':'4', 'value_name': 'r', 'other_data': 89},
]
result = {}
for i in market:
if i["selection_id"] not in result:
result[i["selection_id"]] = {'selection_id': i["selection_id"], 'other_data': i["other_data"], 'value_dict': []}
result[i["selection_id"]]["value_dict"].append({'value': i["value"], "value_name": i["value_name"]})
print(list(result.values()))
输出:
[{'other_data': 89,
'selection_id': 1097,
'value_dict': [{'value': '39', 'value_name': 'b'},
{'value': '52', 'value_name': 'f'}]},
{'other_data': 89,
'selection_id': 1098,
'value_dict': [{'value': '98', 'value_name': 'd'},
{'value': '4', 'value_name': 'r'}]},
{'other_data': 89,
'selection_id': 1099,
'value_dict': [{'value': '11', 'value_name': 'a'},
{'value': '78', 'value_name': 'p'},
{'value': '13', 'value_name': 'y'}]}]
推荐阅读
- java - 无法解析 Cloud Vision API 的符号“google”
- sql - NULL 时创建带零的每日使用表
- python - 在 python 中为数据创建图表,制作财务计算器
- php - Apache Windows 10 ,404 未找到错误(Wamp)
- java - 使用带有 addActionListener 的 JButton 将 JPanel 添加到另一个 JPanel
- javascript - 在 JavaScript 中的所有键值中搜索对象数组
- java - 从大型响应对象中检索一些字段
- tcp - 如何在 kprobe 程序中使用 enum tcp mib 定义?
- reactjs - 当在 react Jest 中运行 npm test 时,我会看到下面的消息,而我要做的就是运行默认情况下在 App.test.js 中提供的测试
- selenium - 从我原来的 chrome 应用程序中获取 cookie 并将其传递到 selenium chrome 浏览器