我有一个使JSON平的函数:
def flat_json(z, sep):
val = {}
for i in z.keys():
if isinstance(z[i], dict):
get = flat_json(z[i], sep)
for j in get.keys():
val[i + sep + j] = get[j]
else:
val[i] = z[i]
return val
flat_json({"a": "b", "c": {"d": "g"}}, '__')
# returns {'a': 'b', 'c__d': 'g'}
但是我还没有弄清楚如何将平面JSON转换回
答案 0 :(得分:1)
取消拼合为任意嵌套的字典,需要为任意路径创建新的字典; c__d
意味着必须有一个与c
键相关联的嵌套字典,因此您可以在其中设置d
。 c__d__e
表示c
是一本字典,其d
键指向另一个字典,是否设置了e
,依此类推。本质上,除了{{1}中的最后一个元素以外的所有内容}是字典中指向另一个字典的键,如果尚未创建,则需要循环创建这些字典。
您可以使用functools.reduce()
来执行此操作,有关key.split('__')
和get_nested_default()
函数的说明,请参见this previous answer of mine:
set_nested()
from functools import reduce
def get_nested_default(d, path):
return reduce(lambda d, k: d.setdefault(k, {}), path, d)
def set_nested(d, path, value):
get_nested_default(d, path[:-1])[path[-1]] = value
def unflatten(d, separator='__'):
output = {}
for k, v in d.items():
path = k.split(separator)
set_nested(output, path, v)
return output
负责为任何数量的键创建那些嵌套字典(如果尚不存在)。 get_nested_default()
负责将路径中的最后一个键与其余键分开,并在最里面的字典中设置值。
当然,这假定输入最初从未在键中使用set_nested()
。但是,只要选择一个不用作输入字典中任何键的子字符串的路径分隔符,就可以将其展平为原始形式。
示例中的演示
__
和使用不同分隔符的更复杂的
:>>> unflatten({'a': 'b', 'c__d': 'g'})
{'a': 'b', 'c': {'d': 'g'}}