Python 如何使用';json';一次读入一个JSON对象的模块?
我有一个千兆字节的JSON文件。该文件由JSON对象组成,每个对象不超过几千个字符,但记录之间没有换行符 使用Python3和Python 如何使用';json';一次读入一个JSON对象的模块?,python,json,Python,Json,我有一个千兆字节的JSON文件。该文件由JSON对象组成,每个对象不超过几千个字符,但记录之间没有换行符 使用Python3和json模块,如何一次从文件中读取一个json对象到内存中 数据位于纯文本文件中。下面是一个类似记录的示例。实际记录包含许多嵌套的字典和列表 以可读格式记录: { "results": { "__metadata": { "type": "DataServiceProviderDemo.Address" }, "
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" } } }
如果您的JSON文档包含一个对象列表,并且您希望一次读取一个对象,那么您可以使用迭代JSON解析器来完成此任务。它只会在需要解码下一个对象时从文件中读取更多内容 请注意,您应该将它与库一起使用,否则您可能不会看到任何性能提高
也就是说,除非您的文件非常大,否则将其完全读入内存,然后使用普通的JSON模块对其进行解析可能仍然是最好的选择。一般来说,将多个JSON对象放入一个文件会使该文件无效、损坏。也就是说,您仍然可以使用 以下内容将在解析器找到完整对象时生成它们:
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中的给定文件对象中读取块,并让decoder
对象从缓冲区解析整个JSON对象。每个被解析的对象都会被交给调用者
像这样使用它:
with open('yourfilename', 'r') as infh:
for data in json_parse(infh):
# process object
仅当您的JSON对象背靠背写入到文件中,且中间没有换行符时,才使用此选项。如果您有换行符,并且每个JSON对象仅限于一行,那么您可以使用,在这种情况下,您可以使用。这里稍微修改一下,它将处理用空格分隔的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"}
然后
发布一个数据样本,至少有几个对象。你的意思是JSON文件是一个对象数组,你想懒洋洋地读取这些对象吗?你是否已经搜索了关于这个主题的其他文章,这里是关于堆栈溢出的?在这里的“相关”侧栏中至少列出了一个我可以看到的。那些帖子怎么没有针对你的具体情况?@poke我不知道你说的“懒散”是什么意思,但是的,我认为这正是我想要的。@MartijnPieters我能找到的其他帖子都没有针对同样的问题。你能分享你找到的解决方案的链接吗?这很有效,谢谢。是的,我处理的文件有背对背的JSON对象。同样在try/except中,我使用了“pass”而不是“break”。这是故意的吗?我无法让它工作。@user3281420:是的,
中断是故意的;它在
循环时中断,因此我们继续从文件中读取下一个块。中断
仅在当前缓冲区中没有要解码的JSON对象时才会触发。@user3281420:通过
仅在缓冲区为空时有效,因为这是while
循环的另一个终止条件。@RonanDejhero:添加.strip()非常简单
调用缓冲区
:result,index=decoder.raw\u decode(buffer.strip())
删除空白,buffer.strip('\n |')
删除一组显式字符。@user2441441:data
是解码到Python对象的JSON数据。这取决于您解码的JSON对象以及如何从中获取键值对。
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'}]