追加到 json 中转储的字典列表,而不用 python 加载列表

Posted

技术标签:

【中文标题】追加到 json 中转储的字典列表,而不用 python 加载列表【英文标题】:Append to list of dictionary dumped in json without loading the list out with python 【发布时间】:2021-09-26 13:19:25 【问题描述】:

在 python 中,我知道我可以将字典列表转储到 .json 文件中,以便使用来自 json 模块的 json.dump() 进行存储。但是,在转储列表后,是否可以在 .json 文件中将更多字典追加到该列表中,而无需显式读取加载完整列表,追加,然后再次转储列表?

例如 在.json我有

['a': 1]

是否可以将'b', 2 添加到.json 的列表中,使文件变为

['a': 1, 'b', 2]

实际列表要长得多(大约一千万),所以我想知道是否有更直接的方法可以做到这一点,而无需从文件中读取整个列表以节省内存。

编辑:

PS:其他文件格式我也开放,只要能有效存储大量字典,并能实现上述功能

【问题讨论】:

JSON 不适合这种格式。看看jsonlines。 不显式读取加载完整列表,追加,然后再次转储列表”是什么意思?您已将列表保存在文件中,但不想读取该文件? @Kshitiz 好吧,我可以读取文件,但我试图避免读取整个列表(json.load() 到一个可能占用大量内存的变量中) 您是否尝试从notepad 打开文件并写入。对不起,但我不确定你是在 Windows 还是其他操作系统中。但是,如果文件很大并且您只想添加 2/3 的东西,那么您可以尝试一下。我不确定它是否有效,所以我没有将它作为答案发布,请尝试后通知我! 【参考方案1】:

JSON 要求列表以 "]" 关闭,因此它本身不可附加。您可以尝试打开文件末尾、删除“]”以及摆弄您尝试编写的新 JSON 来尝试一些棘手的事情。但这很混乱。

关于 JSON 的一个有趣的事情是编码没有换行符。您可以漂亮地打印 JSON,但如果您不这样做,您可以在一行上编写完整的 JSON 记录。所以,不是一个 JSON 列表,而是有一堆行,每一行都是你的 dict 的 JSON 编码。

def append_dict(filename, d):
    with open(filename, 'a', encoding='utf-8') as fp:
        fp.write(json.dumps(d))
        fp.write("\n")

def read_list(filename):
    with open(filename, encoding='utf-8') as fp:
        return [json.loads(line) for line in fp]

由于这个文件现在是一堆 JSON 对象,而不是一个 JSON 列表,任何期望这个文件中有一个列表的程序都会失败。

【讨论】:

这是个好建议。也许只是提到这破坏了与其他需要正常 json 文件的程序的兼容性。【参考方案2】:

在适当的情况下,这听起来可能是一个简单的文件操作问题。如果你确定dump的根数据结构确实是一个json数组,你可以删除文件中最后一个“]”,然后在文件中追加一个新的dump。

您可以附加转储功能。

from json import dumps, dump
import os

#This represents your current dump call
with open('out.json', 'w') as f:
    dump(['version':1], f)

# This removes the final ']'
with open('out.json', 'rb+') as f:
    f.seek(-1, os.SEEK_END)
    f.truncate()

#This appends the new dictionary
with open('out.json', 'a') as f:
    f.write(',')
    f.write(dumps('n':1))
    f.write(']')

如果您使用缩进转储似乎也可以,因为转储函数在任何一种情况下都不以换行符结尾。

处理空数组

如果您第一次转储列表时,它是空的,导致文件“[]”中的 json 数组为空,那么在我的示例中附加一个逗号将导致类似“[,.. .] 你可能不想要。

我看到像i3bar(使用无休止的json数组来发送信息)这样的协议在野外处理这种情况的方式是始终以标头元素开头。在他们的情况下,他们使用 "version": 1

因此,当您进行第一次转储时,请确保将其放在列表的开头 - 也就是说,除非您确定列表中总会有某些内容。

其他说明

尽管 i3bar 等项目使用了这种手动 json hack,但我个人不建议在生产环境中这样做。

【讨论】:

以上是关于追加到 json 中转储的字典列表,而不用 python 加载列表的主要内容,如果未能解决你的问题,请参考以下文章

将大型嵌套字典转储到 JSON 对象中[重复]

如何将字典转储到 JSON 文件?

Python:展平多个嵌套的字典并追加

Python JSON转储/附加到.txt,每个变量都在新行

遍历 Python 字典并特殊追加到新列表?

将列表中的字典追加到熊猫数据框