Python:根据DataFrame点分隔键生成对应层级嵌套JSON
问题描述
我有如下结构的DataFrame:
key text 0 title Lorem ipsum 1 header Lorem ipsum 2 description Lorem ipsum . . . . 10 pyramid.male Lorem ipsum 11 pyramid.male_surplus Lorem ipsum 12 pyramid.female Lorem ipsum 13 pyramid.female_surplus Lorem ipsum . . . . 29 jitterplot.title1 Lorem ipsum 30 jitterplot.metric_1.label Lorem ipsum 31 jitterplot.metric_1.tooltip Lorem ipsum 32 jitterplot.metric_2.label Lorem ipsum 33 jitterplot.metric_2.tooltip Lorem ipsum
key列的取值对应JSON文件中的键名,.代表JSON的一层嵌套层级,最终需要生成的JSON结构如下:
{ "title": "Lorem ipsum", "header": "Lorem ipsum", "description": "Lorem ipsum", "pyramid": { "male": "Lorem ipsum", "male_surplus": "Lorem ipsum", "female": "Lorem ipsum", "female_surplus": "Lorem ipsum" }, "jitterplot": { "title1": "Lorem ipsum", "metric_1": { "label": "Lorem ipsum", "tooltip": "Lorem ipsum" }, "metric_2": { "label": "Lorem ipsum", "tooltip": "Lorem ipsum" } } }
目前我靠自定义解析器手动逐行写入文本文件实现,可扩展性很差,需要符合Pythonic风格的实现方式。
可以用如下代码加载准备好的测试CSV数据:
import pandas as pd url = 'https://raw.githubusercontent.com/Thevesh/Display/master/i18n_sample.csv' df = pd.read_csv(url) df['n_levels'] = df['key'].str.count('\.') # 存储层级数量的列 max_levels = df.n_levels.max() df = df.join(df['key'].str.split('.',expand=True)) df.columns = list(df.columns)[:-max_levels-1] + ['key_' + str(x) for x in range(max_levels+1)]
实现方案
不需要写复杂的自定义文本解析逻辑,直接利用字典的嵌套特性逐行插入即可,代码简洁且支持任意层级的嵌套,完全满足扩展性要求。
最简实现(基于collections.defaultdict)
import json from collections import defaultdict # 递归定义支持自动嵌套的字典结构 def nested_dict(): return defaultdict(nested_dict) result = nested_dict() # 逐行处理key路径和对应文本 for key_path, text in zip(df['key'], df['text']): path_parts = key_path.split('.') current_level = result # 逐层深入到叶子节点的父级 for part in path_parts[:-1]: current_level = current_level[part] # 给叶子节点赋值 current_level[path_parts[-1]] = text # 序列化为格式化的JSON字符串 final_json = json.dumps(result, indent=2, ensure_ascii=False) print(final_json)
无依赖纯dict实现
如果不想引入collections模块,用原生dict也可以实现,逻辑完全一致:
import json import pandas as pd # 加载数据的代码和之前一致 url = 'https://raw.githubusercontent.com/Thevesh/Display/master/i18n_sample.csv' df = pd.read_csv(url) result = {} for key_path, text in zip(df['key'], df['text']): path_parts = key_path.split('.') current_level = result for part in path_parts[:-1]: # 层级不存在则先创建空字典 if part not in current_level: current_level[part] = {} current_level = current_level[part] current_level[path_parts[-1]] = text final_json = json.dumps(result, indent=2, ensure_ascii=False)
这个方案的优势:
- 代码量极小,没有冗余的层级判断、文本拼接逻辑
- 支持任意深度的key嵌套,不需要提前计算最大层级、拆分辅助列
- 后续如果key新增更多层级,不需要修改任何代码即可自动适配
- 输出是标准的Python字典结构,可以直接做二次加工,不需要额外解析文本
内容的提问来源于stack exchange,提问作者Thev
相关产品推荐
相关产品推荐

