如何用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)
代码说明
- 递归处理:遍历每个JSON元素,根据类型(字典、列表、基础类型)分别处理格式
- 列表区分处理:
- 简单元素列表(如
toys)直接拼接为一行,用逗号+空格分隔 - 复杂元素列表(如
pets)将第一个元素紧跟在[后,后续元素保持缩进,最后]与列表起始缩进对齐
- 简单元素列表(如
- 字典格式:保持正常的缩进换行,键值对对齐
内容的提问来源于stack exchange,提问作者Nikhil Agrawal
相关产品推荐
相关产品推荐

