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
タグ