Python JSON操作详解
文章目录
- 一、json模块
- 二、JSON与Python数据类型对应关系
- 三、大文件JSON数据处理
- 四、性能提升工具
-
- 1. ujson
- 2. orjson
- 3. 性能对比
- 五、命令行格式化JSON
-
- 1. json.tool
- 2. jq
-
- 美化输出
- 提取特定字段
- 处理数组
- 组合过滤器和管道
- 构造新的 JSON 对象
- 处理迭代和映射
- 处理条件语句
- 六、总结
本文介绍了Python中处理JSON数据的常用方法与工具,包括JSON文件读写、数据类型映射、字符串转换、命令行工具、性能与大数据处理等方面。
一、json模块
1. 写入JSON文件(json.dump)
json.dump()
方法用于将Python对象序列化为JSON格式并写入文件对象。
参数
indent: 定义缩进级别,使文件更易读。
ensure_ascii: 设为 False 可以正确输出非 ASCII 字符(如中文)。
示例
import json# 要写入的Python数据结构(字典列表)data = [ { \"name\": \"Alice\", \"age\": 30, \"city\": \"New York\", \"hobbies\": [\"Reading\", \"Hiking\"] }, { \"name\": \"Bob\", \"age\": 25, \"city\": \"London\", \"hobbies\": [\"Gaming\", \"Cooking\"] }]# 写入JSON文件with open(\'data.json\', \'w\', encoding=\'utf-8\') as f: json.dump(data, f, indent=4, ensure_ascii=False)
2. 读取JSON文件(json.load)
json.load()
方法用于从文件对象读取JSON数据并解析为Python对象。
示例
import json# 读取JSON文件with open(\'data.json\', \'r\', encoding=\'utf-8\') as f: loaded_data = json.load(f)
3. 字符串与JSON的转换
如果需要处理JSON字符串而不是文件,可以使用json.dumps()
和json.loads()
。
示例
# 将 Python 对象转换为JSON字符串json_string = json.dumps(data, indent=2, ensure_ascii=False)print(\"JSON 字符串:\")print(json_string)# 将JSON字符串转换回 Python 对象python_obj = json.loads(json_string)print(\"转换回的 Python 类型:\", type(python_obj))
二、JSON与Python数据类型对应关系
三、大文件JSON数据处理
对于非常大的JSON文件,可以使用ijson
库进行流式解析,避免一次性加载到内存。
安装
pip install ijson
示例
import ijsonwith open(\'large_file.json\', \'rb\') as f: for item in ijson.items(f, \'item\'): print(item)
四、性能提升工具
1. ujson
ujson
是一个用C编写的高性能JSON编码器/解码器,其API与标准json模块
完全兼容,但在处理速度上显著更快,特别适用于处理大量数据或对性能要求较高的场景。
安装
pip install ujson
示例
import ujsondata = {\"name\": \"Alice\", \"age\": 30}json_string = ujson.dumps(data, ensure_ascii=False)parsed_data = ujson.loads(json_string)# 写入文件with open(\'data.json\', \'w\', encoding=\'utf-8\') as f: ujson.dump(data, f, ensure_ascii=False)# 从文件读取with open(\'data.json\', \'r\', encoding=\'utf-8\') as f: loaded_data = ujson.load(f)
2. orjson
orjson
是一个高性能的JSON库,比标准JSON模块更快,但其API设计与标准json模块
不完全兼容,orjson
没有dump()/load()
方法。
安装
pip install orjson
示例
import orjsondata = {\"name\": \"Alice\", \"age\": 30}json_bytes = orjson.dumps(data) # 返回 bytespython_obj = orjson.loads(json_bytes)print(python_obj)
3. 性能对比
import timeitimport jsonimport orjsonimport ujsondata = {\"key\": \"value\" * 100}def standard_dumps(): return json.dumps(data)def ujson_dumps(): return ujson.dumps(data)def orjson_dumps(): return orjson.dumps(data)print(\"standard json:\", timeit.timeit(standard_dumps, number=10000))print(\"ujson_:\", timeit.timeit(ujson_dumps, number=10000))print(\"orjson:\", timeit.timeit(orjson_dumps, number=10000))# standard json: 0.018705399999999997# ujson_: 0.005678799999999998# orjson: 0.0021665000000000018
五、命令行格式化JSON
1. json.tool
可以在命令行中使用Python内置工具json.tool
格式化JSON文件。
python -m json.tool data.json
或者将输出重定向到新文件。
python -m json.tool data.json > formatted.json
2. jq
jq
命令行工具(Linux/Mac),jq 是一个轻量级、灵活、基于命令行的 JSON 处理器。它的主要功能是解析、过滤、转换、重构和格式化 JSON 数据。
示例json
{ \"name\": \"Alice\", \"age\": 30, \"hobbies\": [\"reading\", \"hiking\", \"coding\"], \"address\": { \"street\": \"123 Main St\", \"city\": \"Springfield\" }, \"email\": null}
美化输出
# 格式化文件jq \'.\' data.json
提取特定字段
# 提取顶级字段jq \'.name\' data.json# 输出:\"Alice\"# 提取嵌套字段jq \'.address.city\' data.json# 输出:\"Springfield\"
处理数组
# 提取所有爱好jq \'.hobbies\' data.json# 输出:[\"reading\", \"hiking\", \"coding\"]# 提取第一个爱好(索引从 0 开始)jq \'.hobbies[0]\' data.json# 输出:\"reading\"# 提取数组的切片(第 1 到第 2 个元素,索引 1 包含,索引 2 不包含)jq \'.hobbies[1:3]\' data.json# 输出:[\"hiking\", \"coding\"]# 遍历数组中的所有元素jq \'.hobbies[]\' data.json# 输出:# \"reading\"# \"hiking\"# \"coding\"
组合过滤器和管道
# 先获取 address 对象,再获取其中的 cityjq \'.address | .city\' data.json# 获取第二个爱好,并将其转换为大写(使用内置函数)jq \'.hobbies[1] | ascii_upcase\' data.json# 输出:\"HIKING\"
构造新的 JSON 对象
# 创建一个只包含 name 和 city 的新对象jq \'{user: .name, city: .address.city}\' data.json# 输出:{\"user\": \"Alice\", \"city\": \"Springfield\"}
处理迭代和映射
map 函数可以对数组中的每个元素应用相同的操作。
# 将所有爱好转换为大写jq \'.hobbies | map(ascii_upcase)\' data.json# 输出:[\"READING\", \"HIKING\", \"CODING\"]
处理条件语句
# 如果 email 为 null,则输出一个默认值jq \'.email // \"no email provided\"\' data.json# 输出:\"no email provided\"