Python - 从字典对象中删除键和值之间的空格

时间:2018-04-09 07:55:40

标签: python json dictionary

我编写了从文件中读取JSON的python脚本,对其进行转换,最后将修改后的JSON写入文件。我读过的JSON没有白色字符,因为我需要最小的尺寸。

问题是当我从文件中读取JSON并调用json.loads(json_content)时,我得到dictionary个对象,而python在键和值之间添加了空格。

文件中的JSON:

{"metadata":{"info":"important info"},"timestamp":"2018-04-06T12:19:38.611Z","content":{"id":"1","name":"name test","objects":[{"id":"1","url":"http://example.com","properties":[{"id":"1","value":"1"}]}]}}

我的剧本:

def get_contents_from_json(file_path):
    with open(file_path) as file:
        contents = file.read()
        print(contents)
        print(type(contents))
        print(sys.getsizeof(contents))
        print(len(contents))
        return json.loads(contents)


if __name__ == '__main__':
    data = get_contents_from_json(STACK_JSON)
    print(data)
    print(type(data))
    print(sys.getsizeof(data))

    string_data = json.dumps(data)
    print(string_data)
    print(type(string_data))
    print(sys.getsizeof(string_data))
    print(len(string_data))

    trimmed = string_data.replace(" ", "")
    print(contents)
    print(type(trimmed))
    print(sys.getsizeof(trimmed))
    print(len(trimmed))

这段代码的输出是:

{"metadata":{"info":"important info"},"timestamp":"2018-04-06T12:19:38.611Z","content":{"id":"1","name":"name test","objects":[{"id":"1","url":"http://example.com","properties":[{"id":"1","value":"1"}]}]}}

<class 'str'>
255
206
{'metadata': {'info': 'important info'}, 'timestamp': '2018-04-06T12:19:38.611Z', 'content': {'id': '1', 'name': 'name test', 'objects': [{'id': '1', 'url': 'http://example.com', 'properties': [{'id': '1', 'value': '1'}]}]}}
<class 'dict'>
240
{"metadata": {"info": "important info"}, "timestamp": "2018-04-06T12:19:38.611Z", "content": {"id": "1", "name": "name test", "objects": [{"id": "1", "url": "http://example.com", "properties": [{"id": "1", "value": "1"}]}]}}
<class 'str'>
273
224
{"metadata":{"info":"importantinfo"},"timestamp":"2018-04-06T12:19:38.611Z","content":{"id":"1","name":"nametest","objects":[{"id":"1","url":"http://example.com","properties":[{"id":"1","value":"1"}]}]}}
<class 'str'>
252
203

说明:

Python从文件中读取JSON,作为文件中相同的字符串。 contents的长度为206,大小为255,因为python中的空字符串有49个字节。

调用json.loads(contents)返回大小为240的dict对象。表示为dict对象的JSON在键名和值之间添加了空格。这就是为什么调用string_data = json.dumps(data)string_data的大小等于274且长度等于224的原因。因此,我尝试使用函数{{1}从string_data中删除空格但是我忘记了一些值有空格,在这个操作之后JSON不正确。

我需要将JSON作为dict对象读取以方便转换,同时我必须保持最小的JSON大小。

有没有办法从.replace(" ", "")对象中删除不必要的空格?

2 个答案:

答案 0 :(得分:3)

您需要关注的是字符串的长度,因此请使用len()来比较结果。

如果您关心生成的JSON大小,您可以轻而易举地告诉json.dumps()不要使用任何空格:

string_data = json.dumps(data, separators=(',', ':'))

演示:

>>> import json
>>> sample = '''{"metadata":{"info":"important info"},"timestamp":"2018-04-06T12:19:38.611Z","content":{"id":"1","name":"name test","objects":[{"id":"1","url":"http://example.com","properties":[{"id":"1","value":"1"}]}]}}'''
>>> data = json.loads(sample)
>>> len(sample)
205
>>> len(json.dumps(data))
224
>>> len(json.dumps(data, separators=(',', ':')))
205

指定separators后,输出长度与原始输入匹配。 separators选项记录为:

  

如果指定,分隔符应该是(item_separator, key_separator)元组。如果缩进(', ', ': '),则默认为None,否则为(',', ': ')要获得最紧凑的JSON表示,您应指定(',', ':')以消除空格。

(大胆强调我的)。

sys.getsizeof()是在这里进行比较的错误工具。该函数为您提供了对象的内存占用(无需递归),此内存占用量是当前Python实现和操作系统特定数据类型大小的实现细节

dict对象在您的操作系统上使用240个字节,但这是一个过度分配的引用哈希表。在具有不同大小指针的不同操作系统上,内存大小会有所不同,无论哪种方式,都不包括引用的字符串对象的大小。对于字符串对象,内存占用很大程度上取决于最高的Unicode代码点;字符串'a'''的覆盖区不同,即使两者都有长度1,因为后者包含非BMP代码点,因此需要 4个字节来存储字符,加上Python对象开销。

接下来,你保存的只有19个空格。压缩会为你节省更多,压缩时空格并不重要:

>>> import zlib
>>> len(zlib.compress(json.dumps(data).encode('utf8'), 9))
155
>>> len(zlib.compress(json.dumps(data, separators=(',', ':')).encode('utf8'), 9))
154

压缩在那里保存了50个字节,而使用紧凑型JSON分隔符则保存了另一个字节。

答案 1 :(得分:2)

json.dumps函数接受多个参数,这些参数允许您指定在将字典写回JSON字符串时希望数据格式化的方式。从它的文档字符串:

  

如果indent是非负整数,那么JSON数组元素和       对象成员将使用该缩进级别进行漂亮打印。缩进       等级0只会插入换行符。 None是最紧凑的       表示。

     

如果已指定,则separators应为(item_separator, key_separator)       元组。如果缩进(', ', ': '),则默认值为None       否则(',', ': ')。要获得最紧凑的JSON表示,       你应该指定(',', ':')来消除空格。

因此,请尝试string_data = json.dumps(data, indent=None, separators=(',', ':'))以获得最紧凑的表示。