当前位置: 首页 > 知识库问答 >
问题:

如何使用“json”模块一次读入一个json对象?

燕禄
2023-03-14

我有一个数千GB的JSON文件。该文件由JSON对象组成,每个对象不超过几千个字符,但记录之间没有换行符。

使用Python 3和json模块,如何一次从文件中读取一个json对象到内存中?

数据在纯文本文件中。这是一个类似记录的示例。实际记录包含许多嵌套字典和列表。

可读格式记录:

{
    "results": {
      "__metadata": {
        "type": "DataServiceProviderDemo.Address"
      },
      "Street": "NE 228th",
      "City": "Sammamish",
      "State": "WA",
      "ZipCode": "98074",
      "Country": "USA"
    }
  }
}

实际格式。新记录一个接一个地开始,没有任何中断。

{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }{"results": { "__metadata": {"type": "DataServiceProviderDemo.Address"},"Street": "NE 228th","City": "Sammamish","State": "WA","ZipCode": "98074","Country": "USA" } } }

共有3个答案

松嘉运
2023-03-14

这里是对MartijnPieters解决方案的一个轻微修改,它将处理用空格分隔的JSON字符串。

def json_parse(fileobj, decoder=json.JSONDecoder(), buffersize=2048, 
               delimiters=None):
    remainder = ''
    for chunk in iter(functools.partial(fileobj.read, buffersize), ''):
        remainder += chunk
        while remainder:
            try:
                stripped = remainder.strip(delimiters)
                result, index = decoder.raw_decode(stripped)
                yield result
                remainder = stripped[index:]
            except ValueError:
                # Not enough data to decode, read more
                break

例如,如果data.txt包含由空格分隔的JSON字符串:

{"business_id": "1", "Accepts Credit Cards": true, "Price Range": 1, "type": "food"} {"business_id": "2", "Accepts Credit Cards": true, "Price Range": 2, "type": "cloth"} {"business_id": "3", "Accepts Credit Cards": false, "Price Range": 3, "type": "sports"}

然后

In [47]: list(json_parse(open('data')))
Out[47]: 
[{u'Accepts Credit Cards': True,
  u'Price Range': 1,
  u'business_id': u'1',
  u'type': u'food'},
 {u'Accepts Credit Cards': True,
  u'Price Range': 2,
  u'business_id': u'2',
  u'type': u'cloth'},
 {u'Accepts Credit Cards': False,
  u'Price Range': 3,
  u'business_id': u'3',
  u'type': u'sports'}]
能正青
2023-03-14

如果您的JSON文档包含一个对象列表,并且您希望一次读取一个对象,那么您可以使用迭代JSON解析器ijson来完成这项工作。它只会在需要解码下一个对象时从文件中读取更多内容。

请注意,您应该将其与YAJL库一起使用,否则您可能看不到任何性能提高。

也就是说,除非您的文件非常大,否则将其完全读入内存,然后使用普通的JSON模块解析它可能仍然是最好的选择。

唐阳飇
2023-03-14

一般来说,在一个文件中放入多个JSON对象会使该文件无效、损坏JSON。也就是说,您仍然可以使用jsondeconder分块解析数据。raw\u decode()方法。

以下内容将在解析器找到完整对象时生成它们:

from json import JSONDecoder
from functools import partial


def json_parse(fileobj, decoder=JSONDecoder(), buffersize=2048):
    buffer = ''
    for chunk in iter(partial(fileobj.read, buffersize), ''):
         buffer += chunk
         while buffer:
             try:
                 result, index = decoder.raw_decode(buffer)
                 yield result
                 buffer = buffer[index:].lstrip()
             except ValueError:
                 # Not enough data to decode, read more
                 break

此函数将从buffersize chunks中的给定文件对象中读取chunks,并让解码器从缓冲区解析整个JSON对象。每个解析的对象都会被传递给调用者。

使用方法如下:

with open('yourfilename', 'r') as infh:
    for data in json_parse(infh):
        # process object

仅当您的JSON对象背靠背写入文件,中间没有换行符时才使用此功能。如果您确实有换行符,并且每个JSON对象仅限于一行,则您有一个JSON Lines文档,在这种情况下,您可以使用加载和解析带有Python中多个JSON对象的JSON文件。

 类似资料:
  • 问题内容: 我有一个千兆字节的JSON文件。该文件由每个不超过几千个字符的JSON对象组成,但是记录之间没有换行符。 使用Python 3和模块,如何一次将一个JSON对象从文件读入内存? 数据在纯文本文件中。这是类似记录的示例。实际记录包含许多嵌套的字典和列表。 以可读格式记录: 实际格式。新记录一个接一个地开始,没有任何中断。 问题答案: 一般而言,将多个JSON对象放入一个文件会使该文件 无

  • 在Java(任何库)中,从像下面这样的json开始(具有嵌套字段、数组和嵌入文档): 然后应用以下jsonpath(作为示例,理想情况下是任何类型的jsonpath) 创建如下所示的json文档: 所以问题是:使用jsonpath不仅可以获取数据,还可以获取所有嵌套字段,并创建一个新的json作为输入的子集? 任何例子都像往常一样受到赞赏 注意:在对此进行了大量思考之后,我得出的结论是,我需要的是

  • 由于是一个对象,并且它有另一个对象,只能有字符串或数字字段,而不能有对象,如何扩展元化学以强制执行此操作。感谢任何帮助

  • 我试图使用另一个JSON模式来验证JSON模式。 要验证的JSON模式示例:https://jsonschema.net/home 验证上述模式的验证模式参考:https://github.com/ajv-validator/ajv/blob/master/lib/refs/json-schema-draft-07.json 从上面的中,如果我删除,我的JSON将变得无效。 我有什么方法可以定义根

  • 问题内容: 有没有办法在同一个python会话中两次加载一个模块? 用一个例子填补这个问题:这是一个模块: 模版 现在,我想两次导入该模块,例如创建一个类的两个实例以实际具有的两个副本。 要已经回答评论中的问题,“如果有人只要创建一个带有变量的类,为什么有人会想这样做”: 您是正确的,但是存在大量的源,必须重写,并且两次加载一个模块将是一个快速修复^^。 问题答案: 是的,您可以两次加载一个模块:

  • 可能重复: 我有一个嵌套的数据结构/JSON,如何访问一个特定的值? 我想迭代一个二维的json对象...对于一维的json对象,我这样做 关于二维的,我该怎么做??