需求说明
想将一个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,则可以保证输出真正的中文字符。