需求说明
想将一个json文件录入MongoDB,如下图所示。
但是原文件是嵌套json对象的形式,如果直接导入MongoDB,会整体变成一个Document:
注:MongoDB中的Document相当于SQL中Row的概念。
而我希望一个Document对应一个式神,即如下图所示的效果。
这就需要将原来的json嵌套对象转为json列表。可以看出,原json中,对象内也包含对象名称的键值对,因此转换过程中无需做什么多余的操作,只要把原先式神名称的键去掉即可,变成如下状态:
实现代码
import json
# 读取json文件,存为json嵌套对象
with open('paj_ssl.json', encoding='utf8') as f:
paj_ssl_json_obj = json.load(f)
# 用列表推导式,提取字典中所有值,转为列表
paj_ssl_json_arr = [paj_ssl_json_obj[key] for key in paj_ssl_json_obj]
# 将json列表存入json文件
with open('data2.json', 'w', encoding='utf8') as f:
json.dump(paj_ssl_json_arr, f, indent=4, ensure_ascii=False)
解释
json数据结构理解
JSON文件最外层的花括号 {} 表示的是一个对象,而方括号 [] 表示的是一个数组。对象和数组都是JSON中的两种结构。
- 对象:用花括号
{}
包裹,是一个无序的名称/值对集合。每个名称/值对之间用逗号 , 分隔,名称和值之间用冒号 : 分隔。例如原先的json,实际上形如:
{
'Tom':{
'name':'Tom',
'age':11,
'hometome':'US'
},
'Jerry':{
'name':'Jerry',
'age':12,
'hometome':'UK'
}
}
- 数组:用方括号
[]
包裹,是一个有序的值集合。每个值之间用逗号 , 分隔。例如转化的目标,实际上形如:
[
{
'name':'Tom',
'age':11,
'hometown':'US'
},
{
'name':'Jerry',
'age':12,
'hometown':'UK'
}
]
语句[obj[key] for key in obj]
(本节解释来源于NewBing)
这段代码是Python中的列表推导式,它的作用是从一个字典中提取所有的值。其中,obj是一个字典,key是字典中的键,obj[key]则是对应键的值。这段代码等价于下面这个for循环:
result = []
for key in obj:
result.append(obj[key])
你可以在Python交互式环境中尝试一下:
>>> obj = {'a': 1, 'b': 2, 'c': 3}
>>> [obj[key] for key in obj]
[1, 2, 3]
解决中文乱码问题的两个参数
encoding='utf8
:指定编码格式为 UTF-8,这样在序列化时,就可以正确地处理中文字符。
ensure_ascii=False
:默认情况下,JSON 序列化时会将非 ASCII 码的字符转义为 ASCII 码,这样会导致中文字符变成 Unicode 码。如果设置为 False,则可以保证输出真正的中文字符。