PythonでもJavaScriptのようにJSONのデータを取得する
JavaScriptにおいてオブジェクトのプロパティを取得するとき、"."または"[]"を使う。
MDN Web Docs: プロパティアクセサーこれはJSONオブジェクトから値を取得するときも同じだ。
プロパティの名前が"."を含めば"[]"を使うが、Pythonでも"."を使ってJSONから値を取得したい。
json.loadsによりJSONをデコードしたとする。
d = {
'a.3': {
'aa': ['b1', 'b2', 'b3'],
},
'b': [
{
'c1': 'C1',
'c2': 'C2',
},
{
'd1': 'D1',
'd2': 'D2',
},
['e1', 'e2', 'e3'],
]
}
import re
prog = re.compile('\[(.+?)\]')
def dot2bra(path):
if '"' in path: return path
path = '["' + ( path.replace('].',']["').replace('.','"]["').replace('[','"][') + '"]' ).replace(']"]',']')
return path
def parse(path):
# keys = re.findall('\[(.+?)\]',path)
keys = prog.findall(path)
for i,key in enumerate(keys): keys[i] = key.strip('"') if key[0]=='"' and key[len(key)-1]=='"' else int(key)
return keys
def get(path, d):
try:
path = dot2bra(path)
keys = parse(path)
for key in keys: d = d[key]
return d
except: return None
from time import time
num = 100000
for path in ('b[1].d2', 'b[2][2]', '["a.3"]["aa"][2]', '["a.3"]["aa"][3]'):
print(path, dot2bra(path), get(path,d))
start = time()
for i in range(num): get(path,d)
print(path, time()-start)
print('-- 比較 --')
start = time()
for i in range(num): d['b'][1]['d2']
print("['b'][1]['d2']", time()-start)
start = time()
for i in range(num): d['b'][2][2]
print("['b'][2][2]", time()-start)
start = time()
for i in range(num): d['a.3']['aa'][2]
print("['a.3']['aa'][2]", time()-start)
パスの指定は文字列で"."記法と"[]"記法の両方に対応する。
try-exceptと正規表現を使うのでキーを指定する方法より20倍以上かかる。
JSONのデータをPythonでも"."で取得する目的だったが、内容は辞書型を"."で取得する方法だったw
2020/01/19 16:24