为什么json.dumps(json.loads(line))的长度大于行的长度?

时间:2019-06-12 13:16:03

标签: python-3.x

为什么json.dumps(json.loads(line))的长度通常大于行的长度?

我有大量的json对象,我试图将坏对象(详细信息)进行分类。因此,我从.jsonl文件中读取了json对象,并将好的json对象(包含很多详细信息)保存在一个新文件中。我整理了约60%的json对象,但文件缩小了约6%,我发现它很奇怪并进行了测试: 我将json对象 line 的长度与json.dumps(json.loads(line))进行比较。对象json.dumps(json.loads(line))的长度为长度的83%至121%。 json.dumps(json.loads(line))的平均长度是的109.5%。

为什么会这样,如何预防呢?如何用Python创建子文件而不将文件增加10%?

我找到了一个例子:

b = r'{"Ä": "ß"}'
print(len(b))
print(len(json.dumps(json.loads(b))))
print(len(json.dumps(json.loads(b), separators=(',', ':'))))

输出为10、20和19。我们看到紧凑编码的区别只是一个空白。但是转储的负载是原始负载的两倍。当我打印出 json.dumps(json.loads(b))时,我得到了

{"\u00c4": "\u00df"}

似乎json.dumps()编码的字符如Ä和ß不太节省空间。我可以尝试使用更好的编码编写自己的转储函数,但我想节省时间。

我刚刚找到Stackoverflow: Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence(以及答案中Finomnis的评论)。

如果我尝试

b = r'{"Ä": "ß"}'
print(len(b))
print(len(json.dumps(json.loads(b), ensure_ascii=False)))

然后在两种情况下我的长度都为10。是的:-D

1 个答案:

答案 0 :(得分:0)

您尝试过compact encoding吗?

json.dumps(json.loads(line), separators=(',', ':'))

此外,如果您确实想节省空间,则可能要禁用ascii编码,但这可能与所有json库都不兼容,因此请谨慎使用。

json.dumps(json.loads(line), separators=(',', ':'), ensure_ascii=False)



示例

import json

a = [[1, 2, 3], {'a':1, 'b':2, 'c':'ä'}]

print(json.dumps(a))
print(json.dumps(a, separators=(',', ':')))
print(json.dumps(a, separators=(',', ':'), ensure_ascii=False))

给予:

[[1, 2, 3], {"a": 1, "b": 2, "c": "\u00e4"}]
[[1,2,3],{"a":1,"b":2,"c":"\u00e4"}]
[[1,2,3],{"a":1,"b":2,"c":"ä"}]