当前位置: 首页 > 面试题库 >

如何在Python中从文件/流懒惰地读取多个JSON值?

竺辉
2023-03-14
问题内容

我想一次从Python的文件/流中读取多个JSON对象。不幸的是json.load()刚刚.read()s,至文件结束-;
似乎没有任何方法可以使用它来读取单个对象或延迟迭代这些对象。

有什么办法吗?使用标准库将是理想的选择,但是如果有第三方库,我会改用它。

目前,我将每个对象放在单独的行上并使用json.loads(f.readline()),但我真的不希望这样做。

使用范例

example.py

import my_json as json
import sys

for o in json.iterload(sys.stdin):
    print("Working on a", type(o))

in.txt

{"foo": ["bar", "baz"]} 1 2 [] 4 5 6

示例会话

$ python3.2 example.py < in.txt
Working on a dict
Working on a int
Working on a int
Working on a list
Working on a int
Working on a int
Working on a int

问题答案:

这是一个非常简单的解决方案。秘诀是尝试,失败并使用异常中的信息正确解析。唯一的限制是该文件必须可搜索。

def stream_read_json(fn):
    import json
    start_pos = 0
    with open(fn, 'r') as f:
        while True:
            try:
                obj = json.load(f)
                yield obj
                return
            except json.JSONDecodeError as e:
                f.seek(start_pos)
                json_str = f.read(e.pos)
                obj = json.loads(json_str)
                start_pos += e.pos
                yield obj

编辑:只是注意到这仅适用于Python> = 3.5。对于更早的版本,失败返回ValueError,并且您必须从字符串中解析出位置,例如

def stream_read_json(fn):
    import json
    import re
    start_pos = 0
    with open(fn, 'r') as f:
        while True:
            try:
                obj = json.load(f)
                yield obj
                return
            except ValueError as e:
                f.seek(start_pos)
                end_pos = int(re.match('Extra data: line \d+ column \d+ .*\(char (\d+).*\)',
                                    e.args[0]).groups()[0])
                json_str = f.read(end_pos)
                obj = json.loads(json_str)
                start_pos += end_pos
                yield obj


 类似资料:
  • 问题内容: 我想知道如何从单个文件夹中读取多个文件(无需指定文件名,只是它们是json文件)。 另外,有可能将它们转换为DataFrame吗? 能给我一个基本的例子吗? 问题答案: 一种选择是使用os.listdir列出目录中的所有文件,然后仅查找以’.json’结尾的文件: 现在,您可以使用pandas DataFrame.from_dict将json(此时为python字典)读入pandas数

  • 我正在尝试实现一个流,该流在其实现中使用自身的另一个实例。流前面有几个常量元素(使用IntStream.concat),所以只要连接的流懒散地创建非常量部分,这就可以工作。我想使用StreamSupport。intStream重载使用intStream获取供应商。concat(它“创建一个懒散连接的流”)应该足够懒惰,只在需要元素时创建第二个拆分器,但即使创建流(而不是计算流)也会溢出堆栈。我如何

  • 问题内容: 我有点头疼,只是因为一个简单,易于表达的陈述使我的脸上有些错误。 我有一个名为的文件,如下所示: 我现在想读取文件。我发现了以下这些语句,但是不起作用: 控制台上显示的错误是这样的: 已编辑 从更改为 并得到了: 问题答案: 该方法( 中没有 )可以直接读取文件: 你正在使用方法,该方法仅用于字符串参数。 编辑:新消息是一个完全不同的问题。在这种情况下,该文件中存在一些无效的。为此,我

  • 问题内容: 我正在尝试使用该模块从python脚本读取json文件。经过一番谷歌搜索后,我发现以下代码: json文件的路径和名称在哪里。我收到以下错误: 问题答案: 该代码用作变量名。它将阴影您导入的模块引用。为变量使用其他名称。 除此之外,代码在接受字符串的同时传递文件对象。 传递文件内容: 或使用接受类似文件的对象。

  • 我正在使用python,我有一个文件(