Python-将大型JSON数组写入文件

use*_*757 3 python serialization json

我正在研究一个可能最终试图将非常大的json数组序列化到文件的过程。因此,将整个阵列加载到内存中,然后仅转储到文件将不起作用。我需要将单个项目流式传输到文件,以避免内存不足的问题。

令人惊讶的是,我找不到执行此操作的任何示例。下面的代码段是我拼凑而成的。有一个更好的方法吗?

first_item = True
with open('big_json_array.json', 'w') as out:
     out.write('[')
     for item in some_very_big_iterator:
          if first_item:
               out.write(json.dumps(item))
               first_item = False
          else:
               out.write("," + json.dumps(item))
     out.write("]")
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 6

虽然您的代码合理,但是可以对其进行改进。您有两个合理的选择,以及一个附加建议。

您的选择是:

  • 不生成数组,而是生成JSON Lines输出。对于生成器中的每个项目,这会在文件中写入一个没有换行符的有效JSON文档,然后再换行。使用默认json.dump(item, out)配置后跟一个out.write('\ n')可以很容易地生成它。您最终得到的文件是每行都有一个单独的JSON文档。

    优点是您不必担心写入或再次读取数据时的内存问题,否则以后在从文件读取数据时会遇到更大的麻烦;如果json不手动跳过首字母[和逗号,就无法使模块迭代加载数据。

    读取JSON行很简单,请参阅在Python中加载和解析具有多个JSON对象的JSON文件

  • 将数据包装在生成器和list子类中,以使其json.dump()接受为列表,然后迭代地写入数据。我将在下面概述。考虑到您现在可能需要反向解决问题,再次使用Python 读取 JSON数据。

我的建议是不要在这里使用JSON。JSON从未为大型数据集设计,它是一种针对较小负载的Web交换格式。这种数据交换有更好的格式。如果您不能偏离JSON,请至少使用JSON行。

您可以使用生成器和一个list子类来迭代地编写一个JSON数组,以使该json库欺骗其接受它作为列表:

class IteratorAsList(list):
    def __init__(self, it):
        self.it = it
    def __iter__(self):
        return self.it
    def __len__(self):
        return 1

with open('big_json_array.json', 'w') as out:
    json.dump(IteratorAsList(some_very_big_iterator), out)
Run Code Online (Sandbox Code Playgroud)

所述IteratorAsList类满足两个测试,该json编码器使得:该对象是一个列表或亚类,以及它们的,它具有比0的长度长; 当满足这些条件时,它将遍历列表(使用__iter__)并对每个对象进行编码。

json.dump()然后,随着编码器产生数据块,该函数将文件写入文件;它永远不会将所有输出保存在内存中。