python - 在Python中的for循环中编写Json

标签 python json for-loop

我正在从 API 下载 Json 文件,我使用以下代码来编写 JSON。循环中的每个项目都会给我一个 JSON 文件。我需要保存它并使用循环从附加的 JSON 文件中提取实体。

for item in style_ls:
    dat = get_json(api, item)
    specs_dict[item] = dat
    with open("specs_append.txt", "a") as myfile:
        json.dump(dat, myfile)
        myfile.close()
    print item

with open ("specs_data.txt", "w") as my file:
    json.dump(spec_dict, myfile)
    myfile.close()

我知道我无法从 specs_append.txt 获取有效的 JSON 格式,但我可以从 specs_data.txt 获取一个。我正在做第一个,因为我的程序至少需要 3-4 天才能完成,而且我的系统很可能会关闭。那么我可以有效地做到这一点吗?

如果没有,我可以从 specs_append.txt 中提取它<{JSON}{JSON}>格式(这不是有效的 JSON 格式)?

如果不是,我应该每次在循环中将specs_dict写入txt文件,这样即使程序终止,我也可以从循环中的该点开始,并且仍然获得有效的json格式?

最佳答案

我提出了几种可能的解决方案。

一种解决方案是编写自定义代码来读取输入文件。我建议在文件中的每个 JSON 对象之前放置一个特殊行,例如: ###

然后你可以编写这样的代码:

import json

def json_get_objects(f):
    temp = ''
    line = next(f)  # pull first line
    assert line == SPECIAL_LINE

    for line in f:
        if line != SPECIAL_LINE:
            temp += line
        else:
            # found special marker, temp now contains a complete JSON object
            j = json.loads(temp)
            yield j
            temp = ''
    # after loop done, yield up last JSON object
    if temp:
        j = json.loads(temp)
        yield j

with open("specs_data.txt", "r") as f:
    for j in json_get_objects(f):
        pass # do something with JSON object j

关于此的两个注释。首先,我只是一遍又一遍地附加到一个字符串;这曾经是在 Python 中执行此操作的一种非常慢的方法,因此如果您使用的是非常旧版本的 Python,请不要这样做,除非您的 JSON 对象非常小。其次,我编写了代码来拆分输入并一次生成一个 JSON 对象,但您也可以使用保证唯一的字符串,通过一次调用 f.read(),然后使用 str.split() 方法函数拆分保证唯一的字符串。

另一个解决方案是将整个文件编写为有效 JSON 对象的有效 JSON 列表。像这样编写文件:

{"mylist":[
# first JSON object, followed by a comma
# second JSON object, followed by a comma
# third JSON object
]}

这需要您的文件附加代码以具有写入权限打开文件,并在写入逗号加换行符之前查找文件中的最后一个 ] ,然后在末尾添加新的 JSON 对象,最后编写 ]} 来关闭文件。如果您这样做,您可以使用 json.loads() 来吸收整个内容并获得 JSON 对象列表。

最后,我建议您也许应该使用数据库。使用 SQLite 或其他东西,然后将 JSON 字符串放入表中。如果你选择这个,我建议使用 ORM 来让你的生活变得简单,而不是手动编写 SQL 命令。

就我个人而言,我赞成第一个建议:编写像 ### 这样的特殊行,然后使用自定义代码来拆分这些标记上的输入,然后获取 JSON 对象。

编辑:好的,第一个建议是假设 JSON 的格式是为了人类可读性,并带有一堆短行:

{
    "foo": 0,
    "bar": 1,
    "baz": 2
}

但它们都是作为一条长线一起运行的:

{"foo":0,"bar":1,"baz":2}

以下是解决此问题的三种方法。

0) 在 ### 之前和之后写入换行符,如下所示:

###
{"foo":0,"bar":1,"baz":2}
###
{"foo":0,"bar":1,"baz":2}

然后每个输入行将交替为 ### 或完整的 JSON 对象。

1) 只要 SPECIAL_LINE 完全唯一(永远不会出现在 JSON 中的字符串内),您就可以执行以下操作:

with open("specs_data.txt", "r") as f:
    temp = f.read()  # read entire file contents
    lst = temp.split(SPECIAL_LINE)
    json_objects = [json.loads(x) for x in lst]
    for j in json_objects:
        pass # do something with JSON object j

.split() 方法函数可以为您将 temp 字符串拆分为 JSON 对象。

2) 如果您确定每个 JSON 对象中永远不会有换行符,您可以简单地将 JSON 对象一个接一个地写入文件,并在每个对象后面添加一个换行符;然后假设每一行都是一个 JSON 对象:

import json

def json_get_objects(f):
    for line in f:
        if line.strip():
            yield json.loads(line)

with open("specs_data.txt", "r") as f:
    for j in json_get_objects(f):
        pass # do something with JSON object j

我喜欢选项 (2) 的简单性,但我喜欢选项 (0) 的可靠性。如果换行符作为 JSON 对象的一部分写入,选项 (0) 仍然有效,但选项 (2) 会出错。

同样,您也可以简单地使用带有 ORM 的实际数据库 (SQLite),并让数据库关心细节。

祝你好运。

关于python - 在Python中的for循环中编写Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24423751/

相关文章:

python - mysql查询的响应以一种顺序返回键,但使用python以不同的顺序保存

python - pylint 在 conda 环境中失败

python - python中的shell脚本中的 "&"相当于什么

python - HTTP请求内容为空

swift - 如何反复更新 UILabel 并控制其变化速度?

javascript - 具有复杂 json 的 CORS 兼容 $.ajax 后调用

javascript - jQuery 将动态单元格添加到表中的静态单元格

json - 错误函数未返回 JSON 格式

Java:使用for循环返回列表

c++ - 每次循环运行时如何更改for循环中的对象