You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python的json.dumps实现列表元素逗号空格分隔同行?

问题

现有一段JSON数据,列表内元素默认换行显示:

json_str = '''
{
    "name": "John",
    "age": 30,
    "pets": [
        {
            "name": "Fluffy",
            "type": "cat",
            "toys": [
                "ball",
                "string",
                "box"
            ]
        },
        {
            "name": "Fido",
            "type": "dog",
            "toys": [
                "bone",
                "frisbee"
            ]
        }
    ]
}
'''

需要将其格式化为以下样式:列表起始符号[后紧跟第一个元素,嵌套的简单元素列表全部放在同一行,元素间用逗号+空格分隔:

{
    "name": "John",
    "age": 30,
    "pets": [ {
          "name": "Fluffy",
          "type": "cat",
          "toys": [ "ball", "string", "box" ]
        }, {
           "name": "Fido",
           "type": "dog",
           "toys": [ "bone", "frisbee" ]
     } ]
}

尝试过自定义JSONEncoder但无效,代码如下:

class ObjectEncoder(JSONEncoder):
    def default(self, o):
        if isinstance(o, Enum):
            return o.name

        if isinstance(o, list):
            return ", ".join(json.dumps(i, indent=self.indent) for i in o)
        ## Remove all attributes which are None;

        for key, value in list(o.__dict__.items()):
            if value is None:
                del o.__dict__[key]
        return o.__dict__
解决方案

问题原因

自定义JSONEncoder的default方法仅用于处理Python内置JSON序列化器无法识别的类型,列表本身属于可直接序列化的类型,因此不会触发该方法内的列表处理逻辑,导致自定义格式无效。

实现代码

通过递归遍历JSON对象,根据元素类型自定义输出格式:

import json

def custom_json_format(obj, indent=4, current_indent=0):
    indent_str = " " * current_indent
    # 处理字典类型
    if isinstance(obj, dict):
        lines = ["{"]
        items = list(obj.items())
        for idx, (key, value) in enumerate(items):
            key_str = json.dumps(key)
            value_str = custom_json_format(value, indent, current_indent + indent)
            line = f"{indent_str}{' ' * indent}{key_str}: {value_str}"
            # 非最后一个元素加逗号
            if idx != len(items) - 1:
                line += ","
            lines.append(line)
        lines.append(f"{indent_str}}}")
        return "\n".join(lines)
    # 处理列表类型
    elif isinstance(obj, list):
        # 判断是否为简单元素列表(字符串、数字、布尔值、None)
        all_simple = all(isinstance(item, (str, int, float, bool, type(None))) for item in obj)
        if all_simple:
            # 简单元素列表直接放在一行
            items_str = ", ".join(json.dumps(item) for item in obj)
            return f"[ {items_str} ]"
        else:
            # 复杂元素列表(如包含字典),第一个元素紧跟在[后
            lines = ["["]
            for idx, item in enumerate(obj):
                item_str = custom_json_format(item, indent, current_indent + indent)
                if idx == 0:
                    # 第一个元素去掉开头的缩进,紧跟在[后面
                    line = f"{indent_str} {item_str.lstrip()}"
                else:
                    line = f"{indent_str}{' ' * indent}{item_str.lstrip()}"
                if idx != len(obj) - 1:
                    line += ","
                lines.append(line)
            lines.append(f"{indent_str} ]")
            return "\n".join(lines)
    # 处理基础类型(直接序列化)
    else:
        return json.dumps(obj)

# 测试使用
if __name__ == "__main__":
    json_str = '''
    {
        "name": "John",
        "age": 30,
        "pets": [
            {
                "name": "Fluffy",
                "type": "cat",
                "toys": [
                    "ball",
                    "string",
                    "box"
                ]
            },
            {
                "name": "Fido",
                "type": "dog",
                "toys": [
                    "bone",
                    "frisbee"
                ]
            }
        ]
    }
    '''
    # 解析JSON为Python对象
    data = json.loads(json_str)
    # 生成自定义格式的JSON字符串
    formatted_json = custom_json_format(data)
    print(formatted_json)
    # 写入文件
    with open("formatted_output.json", "w", encoding="utf-8") as f:
        f.write(formatted_json)

代码说明

  1. 递归处理:遍历每个JSON元素,根据类型(字典、列表、基础类型)分别处理格式
  2. 列表区分处理:
    • 简单元素列表(如toys)直接拼接为一行,用逗号+空格分隔
    • 复杂元素列表(如pets)将第一个元素紧跟在[后,后续元素保持缩进,最后]与列表起始缩进对齐
  3. 字典格式:保持正常的缩进换行,键值对对齐

内容的提问来源于stack exchange,提问作者Nikhil Agrawal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:18:21