python - 将包含多个嵌套字典的字典转换为 .csv
问题描述
我在 Python 中有一个包含多个嵌套字典的字典,我想将它们写入一个 csv 文件。
字典看起来像这样:
dict = {'case1':{'variant1':{'Name':['1','2','3'],'Values':[1,2,3],'Unit':['one','two','three']}},
'variant2':{'Name':['1','2','3'],'Values':[1,2,3],'Unit':['one','two','three']},
'case2':{'variant1':{'Name':['1','2','3'],'Values':[1,2,3],'Unit':['one','two','three']}},
'variant2':{'Name':['1','2','3'],'Values':[1,2,3],'Unit':['one','two','three']}}
因此,具有不同变体的多个案例,每个变体包含三个对应名称、值和单位的列表。如前所述,我想将此 dict 转换为 csv 文件,理想情况下,不同情况下的变体很容易区分。由于 csv 将主要在 Excel 中使用,我将举例说明我想象它在 Excel 中的外观。理想是这样的: test_dict2csv
我知道如何将单个变体(因此一组名称、值和单位)写入 csv,其代码如下所示:
keys = sorted(dict['case1']['variant1'].keys())
with open("test_output.csv", "w") as outfile:
writer = csv.writer(outfile,delimiter=';')
writer.writerow(keys)
writer.writerows(zip(*[dict['case1']['variant1'][key] for key in keys]))
但我不知道如何在同一行向下添加下一个变体和案例。
如果有人有想法,我将不胜感激:)
解决方案
如果要为每个元素生成一条记录,每个列表中生成一个元素,可以先展平字典,然后像这样编写:
import csv
from pprint import pprint
dict_data = {
"c1": {
"v1": {
"Name": ["s111", "s112", "s113"],
"Values": [111, 112, 113],
"Unit": ["11one", "11two", "11three"],
},
"v2": {
"Name": ["s121", "s122", "s123"],
"Values": [121, 122, 123],
"Unit": ["12one", "12two", "12three"],
},
},
"c2": {
"v1": {
"Name": ["s211", "s212", "s213"],
"Values": [211, 212, 213],
"Unit": ["21one", "21two", "21three"],
},
"v2": {
"Name": ["s221", "s222", "s223"],
"Values": [221, 222, 223],
"Unit": ["22one", "22two", "22three"],
},
},
}
def flatten_dict(curr_dict, curr_key=""):
new_dict = {}
for new_key, value in curr_dict.items():
if curr_key == "":
combined_key = new_key
else:
combined_key = curr_key + "_" + new_key
if isinstance(value, dict):
new_dict.update(flatten_dict(value, combined_key))
else:
new_dict[combined_key] = value
return new_dict
flat = flatten_dict(dict_data)
pprint(flat)
keys = sorted(flat.keys())
with open("test_output_all.csv", "w") as outfile:
writer = csv.writer(outfile, delimiter=";")
writer.writerow(keys)
writer.writerows(zip(*[flat[key] for key in keys]))
(我只是将 dict 更改为更清楚哪个值是哪个,并且键名更短,结构与您的相似)。这打印:
{'c1_v1_Name': ['s111', 's112', 's113'],
'c1_v1_Unit': ['11one', '11two', '11three'],
'c1_v1_Values': [111, 112, 113],
'c1_v2_Name': ['s121', 's122', 's123'],
'c1_v2_Unit': ['12one', '12two', '12three'],
'c1_v2_Values': [121, 122, 123],
'c2_v1_Name': ['s211', 's212', 's213'],
'c2_v1_Unit': ['21one', '21two', '21three'],
'c2_v1_Values': [211, 212, 213],
'c2_v2_Name': ['s221', 's222', 's223'],
'c2_v2_Unit': ['22one', '22two', '22three'],
'c2_v2_Values': [221, 222, 223]}
在文件中:
c1_v1_Name;c1_v1_Unit;c1_v1_Values;c1_v2_Name;c1_v2_Unit;c1_v2_Values;c2_v1_Name;c2_v1_Unit;c2_v1_Values;c2_v2_Name;c2_v2_Unit;c2_v2_Values
s111;11one;111;s121;12one;121;s211;21one;211;s221;22one;221
s112;11two;112;s122;12two;122;s212;21two;212;s222;22two;222
s113;11three;113;s123;12three;123;s213;21three;213;s223;22three;223
如果您绝对需要图片中的标题,则应该对标题行进行一些预处理,以便在单独的行上打印每个嵌套级别。
干杯!
推荐阅读
- reactjs - 如何在react.js中使用确认模式实现滑动删除
- javascript - 如何根据角度4中的日期过滤记录
- php - 如何在 php 中获取反应 URL 以创建 API?
- jquery - Laravel whereRaw,或带有 FIND_IN_SET 查询的 WhereRaw 未专门运行
- c# - 裁剪后如何将base64图像源发送到控制器(使用croppie)
- react-native - 如何在不使用 iCloud 的情况下从文件管理器上传文件?
- php - Laravel Group By 和 Sum 每个分组的行
- android - 键盘没有为 WebView 打开
- javascript - 全屏时如何在 Clappr 视频播放器上放置自定义叠加层?
- javascript - 如何使用 css 网格为 javascript 事件侦听器设置动画