我正在解决一个问题,我有一个json对象文件,如下所示:
{
"id": "111",
"name": {
"firstname": "Tamara",
"lastname": "Myers"
},
"address": {
"street": "20722 Coleman Villages,East Rose",
"zip": "71064-5894"
}
}
我想将其转换为:
{
"id": "111",
"name_firstname": "Tamara",
"name_lastname": "Myers",
"address_street": "20722 Coleman Villages,East Rose",
"address_zip": "71064-5894"
}
我无法做到这一点,因为我们可能在其他json对象中有更多字段,这些字段在上面的例子中没有给出。
例如"Job":{"Engineer":"Junior","domain":"civil"}
。并且所有json对象中的嵌套级别也是不规则的。
答案 0 :(得分:2)
您需要一个递归函数:与while
或for
循环不同,它不关心嵌套级别。
(递归函数只是一个调用自身的函数)
想法是
def flat_keys(obj, new_obj={}, keys=[]):
for key, value in obj.items():
if isinstance(value, dict):
# call the function again if the value is a dict
# we go one step deeper: obj[key]
# give the new_obj (by reference, so each call edit the *same* object)
# give to used keys: keys + [key]
flat_keys(obj[key], new_obj, keys + [key])
else:
new_obj['_'.join(keys + [key])] = value
return new_obj
new_obj = flat_keys(json.JSONDecoder().decode("your object"))
print(new_obj)
答案 1 :(得分:2)
你需要一个递归函数。但是这个比其他提供的更简单。它还将基础案例放在首位,这将有助于堆栈大小。我不能让它拖尾递归。
def merge_keys(d):
to_return = {}
for key, value in d.items():
if not isinstance(value, dict):
to_return[key] = value
else:
for merged_key, merged_value in merge_keys(value).items():
to_return["_".join((key, merged_key))] = merged_value
return to_return
答案 2 :(得分:1)
我相信递归生成器会很好:
def nested_to_flat(data):
for k, v in data.items():
if isinstance(v, dict):
for x, y in nested_to_flat(v):
yield ('%s_%s' % (k, x), y)
continue
yield (k, v)
并使用如下:
result = {k: v for k, v in nested_to_flat(data)}
答案 3 :(得分:1)
import sys
sys.path.insert(0, '.')
from sys import stderr
def pare(data, key, is_verbose=False):
parts = key.split('.')
i = 0
ptr = data
for part in parts:
if is_verbose is True:
if i > 0:
stderr.write(' -> ')
stderr.write(part)
try:
if issubclass(ptr.__class__, list) is True:
ptr = ptr[int(part)]
else:
ptr = ptr[part]
except:
if is_verbose is True:
stderr.write("\n")
raise ValueError("Could not descend to child node: %s" % (part))
i += 1
if is_verbose is True:
stderr.write("\n")
return ptr
def path_list(dictionary, path):
key_path_list = []
if dictionary.__class__.__name__ == 'dict':
if len(dictionary.keys())>0:
i = 0
n = len(dictionary.keys())
while i< n:
new_path = dictionary.keys()[i]
i += 1
key_path = path + '.' + new_path
key_path_list.append(key_path)
else:
pass
return key_path_list
def rec_data(data, key_path):
pared = pare(data, key_path)
value = []
nd = {}
if pared.__class__.__name__ == 'dict':
paths = path_list(pared, key_path)
for p in paths:
if p in paths:
sl = pare(data, p)
nd[p] =sl
value.append(sl)
else:
pass
rec_data(data, p)
else:
nd[key_path] = pared
return nd
def main():
json = {
"id": "111",
"name": {
"firstname": "Tamara",
"lastname": "Myers"
},
"address": {
"street": "20722 Coleman Villages,East Rose",
"zip": "71064-5894"
}
}
dic = {}
for k,v in json.items():
dic.update(rec_data(json,k))
print dic
if __name__ == "__main__":
main()
答案 4 :(得分:0)
在Python中,您可以在fly
创建密钥dic = {}
dic["key"] = value
dic["key"] = "value"
print dic
{'key': 'value'}
你可以用你的对象做这样的事情:
myNewDic = {}
for key, value in dic.items():
if isinstance(value,dict):
for k, v in value.items():
myNewDic[key+"_"+k] = v
else:
myNewDic[key] = value
检查是否有效,我想我正在路上。
快乐编码