Python中JSON与字典/列表的相互转换详解

前言

在日常开发中,JSON(JavaScript Object Notation)是数据交换最常用的格式之一。Python 内置的 json 模块提供了完整的 JSON 与 Python 数据类型之间的转换能力。本文将系统总结 JSON 字符串 ↔ Python 字典/列表 的相互转换知识,帮助你彻底掌握这一技能。


一、核心对应关系

理解类型映射是掌握转换的关键:

JSON 类型 Python 类型
object {} dict(字典)
array [] list(列表)
string "..." str(字符串)
number(整数) int
number(小数) float
true / false True / False
null None

重要规律:

  • JSON 的 对象 对应 Python 的 字典

  • JSON 的 数组 对应 Python 的 列表

  • Python 的字典/列表互相嵌套时,转换后依然是嵌套结构


二、四个核心函数

json 模块中最常用的四个函数,记住一句话:

带 s 的操作字符串,不带 s 的操作文件。

函数 方向 输入 输出
json.loads() JSON → Python 字符串 dict / list
json.dumps() Python → JSON dict / list 字符串
json.load() JSON → Python 文件对象 dict / list
json.dump() Python → JSON dict / list 写入文件

三、JSON 字符串 → 字典 / 列表

3.1 JSON 对象转字典

python

python 复制代码
import json

json_str = '{"name": "小明", "age": 18, "city": "北京"}'
result = json.loads(json_str)

print(result)
print(type(result))

输出:

text

复制代码
{'name': '小明', 'age': 18, 'city': '北京'}
<class 'dict'>

3.2 JSON 数组转列表

python

python 复制代码
import json

json_str = '[1, 2, 3, "hello", true, null]'
result = json.loads(json_str)

print(result)
print(type(result))

输出:

text

python 复制代码
[1, 2, 3, 'hello', True, None]
<class 'list'>

3.3 嵌套结构转换

python

python 复制代码
import json

json_str = '''
{
    "users": [
        {"name": "小明", "age": 18},
        {"name": "小红", "age": 20}
    ],
    "total": 2
}
'''

result = json.loads(json_str)
print(result["users"][0]["name"])  # 小明
print(result["total"])              # 2

嵌套结构会按照对应关系逐层转换。


四、字典 / 列表 → JSON 字符串

4.1 字典转 JSON

python

python 复制代码
import json

data = {"name": "小明", "age": 18, "city": "北京"}
json_str = json.dumps(data, ensure_ascii=False)

print(json_str)
print(type(json_str))

输出:

python 复制代码
text

{"name": "小明", "age": 18, "city": "北京"}
<class 'str'>

4.2 列表转 JSON

python

python 复制代码
import json

data = [1, 2, 3, "hello", True, None]
json_str = json.dumps(data, ensure_ascii=False)

print(json_str)
'''输出:'''

text

[1, 2, 3, "hello", true, null]

注意:Python 的 True/False/None 会变成 JSON 的 true/false/null。

4.3 嵌套结构转换

python

python 复制代码
import json

data = {
    "users": [
        {"name": "小明", "age": 18},
        {"name": "小红", "age": 20}
    ],
    "total": 2
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

输出:

python 复制代码
json

{
  "users": [
    {
      "name": "小明",
      "age": 18
    },
    {
      "name": "小红",
      "age": 20
    }
  ],
  "total": 2
}

五、dumps 常用参数详解

json.dumps() 支持多个实用参数,掌握它们能让输出更符合需求。

5.1 ensure_ascii

控制非 ASCII 字符是否转义。

python

python 复制代码
data = {"city": "北京"}

# 默认 True,中文被转义
print(json.dumps(data))
# {"city": "\u5317\u4eac"}

# 设为 False,中文原样输出(推荐)
print(json.dumps(data, ensure_ascii=False))
# {"city": "北京"}

建议:只要包含中文,都加上 ensure_ascii=False。

5.2 indent

美化输出,设置缩进空格数。

python

python 复制代码
data = {"name": "小明", "age": 18}

print(json.dumps(data, ensure_ascii=False, indent=2))

输出:

json

python 复制代码
{
  "name": "小明",
  "age": 18
}

indent=None(默认)时输出为紧凑的一行。

5.3 sort_keys

按键名排序输出。

python

python 复制代码
data = {"c": 3, "a": 1, "b": 2}

print(json.dumps(data, sort_keys=True))
# {"a": 1, "b": 2, "c": 3}

5.4 separators

自定义分隔符,用于压缩输出。

python

python 复制代码
data = {"a": 1, "b": 2}

# 默认: (', ', ': ')
# 压缩: (',', ':')
print(json.dumps(data, separators=(',', ':')))
# {"a":1,"b":2}

5.5 参数速查表

参数 说明 常用值
ensure_ascii 是否转义非 ASCII 字符 False(中文场景)
indent 缩进空格数 2 或 4
sort_keys 按键排序 True / False
separators 分隔符 (',', ':')
default 处理无法序列化的对象 自定义函数

六、文件读写操作

处理文件时用 json.load() 和 json.dump()(不带 s)。

6.1 从文件读取 JSON

python

python 复制代码
import json

with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)

print(data)
print(type(data))

6.2 写入 JSON 到文件

python

python 复制代码
import json

data = {"name": "小明", "age": 18, "hobbies": ["读书", "游泳"]}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

务必指定 encoding="utf-8",否则中文可能乱码。


七、进阶技巧

7.1 处理特殊类型(如 datetime)

JSON 默认不支持日期、自定义对象等类型,可通过 default 参数处理。

python

python 复制代码
import json
from datetime import datetime

def default_handler(obj):
    if isinstance(obj, datetime):
        return obj.strftime("%Y-%m-%d %H:%M:%S")
    raise TypeError(f"无法序列化: {type(obj)}")

data = {"time": datetime.now()}
print(json.dumps(data, default=default_handler, ensure_ascii=False))
# {"time": "2024-01-01 12:00:00"}

7.2 object_hook 自定义解析

json.loads() 支持 object_hook,可在解析时对字典做处理。

python

python 复制代码
import json

def hook(d):
    if "age" in d:
        d["age"] = int(d["age"])
    return d

json_str = '{"name": "小明", "age": "18"}'
result = json.loads(json_str, object_hook=hook)
print(result)  # {'name': '小明', 'age': 18}

7.3 深拷贝的替代用法

利用 JSON 转换可以实现简单的深拷贝(仅限基础类型):

python

python 复制代码
import json

original = {"a": [1, 2, 3], "b": {"c": 4}}
copy = json.loads(json.dumps(original))

copy["a"].append(4)
print(original["a"])  # [1, 2, 3]  原数据不受影响
print(copy["a"])      # [1, 2, 3, 4]

7.4 判断字符串是否为合法 JSON

python

python 复制代码
import json

def is_valid_json(s):
    try:
        json.loads(s)
        return True
    except json.JSONDecodeError:
        return False

print(is_valid_json('{"a": 1}'))  # True
print(is_valid_json('{a: 1}'))    # False

八、常见错误与注意事项

8.1 单引号不是合法 JSON

JSON 标准要求字符串和键名使用双引号。

python

python 复制代码
import json

# 错误:单引号
json.loads("{'name': '小明'}")
# json.decoder.JSONDecodeError

# 正确:双引号
json.loads('{"name": "小明"}')

8.2 尾随逗号不合法

python

python 复制代码
# 错误
json.loads('{"a": 1, "b": 2,}')

# 正确
json.loads('{"a": 1, "b": 2}')

8.3 元组会被转为列表

python

python 复制代码
import json

data = (1, 2, 3)
print(json.dumps(data))       # [1, 2, 3]
print(type(json.loads("[1,2,3]")))  # <class 'list'>

8.4 字典的键必须是字符串

JSON 对象的键必须是字符串,非字符串键会被转换。

python

python 复制代码
import json

data = {1: "a", 2: "b"}
print(json.dumps(data))  # {"1": "a", "2": "b"}

8.5 精度丢失问题

浮点数在转换中可能出现精度问题,涉及金额等高精度场景建议用字符串传输。

8.6 异常处理

python

python 复制代码
import json

try:
    data = json.loads('{"a": 1}')
except json.JSONDecodeError as e:
    print(f"解析失败: {e}")

九、完整示例:综合运用

python

python 复制代码
import json

# 原始 Python 数据(字典 + 列表嵌套)
data = {
    "class": "三年二班",
    "students": [
        {"name": "小明", "age": 18, "scores": [90, 85, 88]},
        {"name": "小红", "age": 20, "scores": [95, 92, 98]}
    ],
    "count": 2
}

# 1. 转换为 JSON 字符串
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("=== JSON 字符串 ===")
print(json_str)

# 2. 保存到文件
with open("students.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# 3. 从文件读取
with open("students.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

# 4. 访问数据
print("\n=== 访问数据 ===")
print(loaded["class"])
for s in loaded["students"]:
    print(f'{s["name"]} 平均分: {sum(s["scores"]) / len(s["scores"]):.2f}')

十、总结

核心口诀

  1. JSON 对象 ↔ dict,JSON 数组 ↔ list

  2. 带 s 操作字符串,不带 s 操作文件

  3. load 是解析(JSON→Python),dump 是序列化(Python→JSON)

  4. 中文场景记得加 ensure_ascii=False

  5. 文件读写记得指定 encoding="utf-8"

转换方向速查

需求 使用函数
JSON 字符串 → 字典/列表 json.loads()
字典/列表 → JSON 字符串 json.dumps()
JSON 文件 → 字典/列表 json.load()
字典/列表 → JSON 文件 json.dump()

掌握以上内容,基本可以应对 Python 开发中 99% 的 JSON 转换场景。如果涉及超大文件、高精度数值或高性能需求,可以考虑 orjson、ujson 等第三方库作为补充。


如果本文对你有帮助,欢迎点赞、收藏、评论三连支持一下! 🎉

相关推荐
梦想不只是梦与想1 小时前
SQLAlchemy:查询与操作 (三)
数据库·python·sqlalchemy
计算机编程指导师1 小时前
【大数据毕设】基于Hadoop+Django乳腺癌数据分析与可视化系统选题推荐 源码 毕业设计 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·毕业设计·课程设计·乳腺癌
打工仔折腾 AI1 小时前
鸿蒙版ToDesk远控实测:蓝牙键鼠、双模式鼠标与跨端剪贴板怎么用
后端·python·华为·性能优化·计算机外设·harmonyos·ai agent 实战
启观川1 小时前
数据结构与算法 -第 3 章 常用算法-回溯算法
数据结构·笔记·python·算法
计算机编程指导师1 小时前
Python毕设怎么做?基于hadoop的商家优惠券营销效果数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·spark·毕业设计·课程设计·优惠券
计算机编程指导师2 小时前
【Python毕设推荐】基于Hadoop+Spark的商场商铺运行数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·spark·课程设计·商场商铺
haluhalu.2 小时前
Agent = LLM + 上下文 + 工具(含观察 / 动作空间、ReAct 循环)
前端·javascript·人工智能·python·react.js·机器学习·个人开发
mldong2 小时前
给 Django Admin 加审批流:一行前端代码没写,298 行接上工作流引擎
后端·python·架构
瑶山2 小时前
Windows 11 一键安装命令安装 WSL2到D盘
windows·wsl