簡體   English   中英

如何在python中加載多個json對象

[英]how to load multiple json objects in python

我在以下格式的json文件中有 10,000 個 json 對象:

{ "a": 1,
  "b" : 2,
  "c" : {
          "d":3
        }
}{ "e" : 4,
  "f" : 5,
  "g" : {
         "h":6
        }
}

如何將這些加載為 json 對象?

我嘗試過的兩種方法都有相應的錯誤:

方法一:

>>> with open('test1.json') as jsonfile:
...     for line in jsonfile:
...             data = json.loads(line)
... 

錯誤 :

Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.5/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 1 (char 10)

方法二:

>>> with open('test1.json') as jsonfile:
...     data = json.load(jsonfile)      
... 

錯誤 :

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python3.5/json/__init__.py", line 268, in load
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
  File "/usr/lib/python3.5/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.5/json/decoder.py", line 342, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 7 column 1 (char 46)
>>> 

我已經閱讀了相關的問題,但沒有一個有幫助。

您描述的文件內容不是有效的 JSON 對象,這就是機器人方法不起作用的原因。

要轉換可以使用json.load(fd)加載的內容,您必須:

  1. 在文件的開頭添加一個[
  2. 在每個對象之間添加一個,
  3. 在文件的最后添加一個]

那么你可以使用方法2。例如:

[ { "a": 1,
    "b" : 2,
    "c" : {
      "d":3
    }
  }, { "e" : 4,
       "f" : 5,
       "g" : {
         "h":6
       }
  }
]

是一個有效的 JSON 數組

如果文件格式與您描述的完全一樣,您可以

with open(filename, 'r') as infile:
    data = infile.read()
    new_data = data.replace('}{', '},{')
    json_data = json.loads(f'[{new_data}]')

正如丹尼爾在評論中所說,重點是 JSONs 塊的開始/結束模式。當你更新時,模式是}{

將所有數據加載到一個字符串中,將此模式替換為您可以處理的模式,並將其拆分為有效 JSON 數據的字符串列表。 最后,遍歷列表。

{ "a": 1,
"b" : 2,
"c" : {
        "d":3
        }
}{ "e" : 4,
"f" : 5,
"g" : {
        "h":6
        }
}

將數據加載到 json 有效字符串列表

with open('/home/mauro/workspace/test.json') as fp:
    data = fp.read()

更換圖案

data = data.replace('}{', '}\n\n{')

然后,將其拆分為有效的 json 字符串列表

data = data.split('\n\n')

最后,遍歷 json 字符串列表

for i in data:
    print json.loads(i)

我相信,如果您不想更改源文件,最好的方法是使用 json.JSONDecoder.raw_decode() 它允許您遍歷文件中的每個有效 json 對象

from json import JSONDecoder, JSONDecodeError

decoder = JSONDecoder()
content = '{ "a": 1,  "b": 2,  "c": { "d":3 }}{ "e": 4, "f": 5,  "g": {"h":6 } }'

pos = 0
while True:
    try:
        o, pos = decoder.raw_decode(content, pos)
        print(o)
    except JSONDecodeError:
        break

會打印你的兩個 Json 對象

[
    { 
      "a": 1,
      "b" : 2,
      "c" : {
              "d":3
            }
    },
    { 
      "e" : 4,
      "f" : 5,
      "g" : {
             "h":6
            }
    }
]

首先你的 json 文件應該是這樣的,然后像 json.loads(file.read()) 一樣加載你的文件

@Thiago的答案對我有用,但前提是 pos 加一,否則它總是只打印一個對象

像這樣:

from json import JSONDecoder, JSONDecodeError

def json_decoder(data):
    decoder = JSONDecoder()
    pos = 0
    result = []
    while True:
        try:
            o, pos = decoder.raw_decode(data, pos)
            result.append(o)
            pos +=1
        except JSONDecodeError:
            break
    return result

我創建了這個腳本,它利用了異常,包括 json 結束的字符:

import json
from json.decoder import JSONDecodeError

with open("file.json", 'r') as file:
    contents = file.read()
start=0
end=len(contents)
json_objects=[]
while start < len(contents):
    try:
        json_objects.append(json.loads(contents[start:end]))
        print(f"Loaded from {start} to {end}")
        start=end
        end=len(contents)
    except JSONDecodeError as e:
        end=start+e.pos
for json_object in json_objects:
    print(len(json.dumps(json_object)))

它根本沒有效率,需要將整個文件加載到內存中,但它確實有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM