Python 打印嵌套JSON的父数据和子数据
我有以下类型的JSON。在另一个表中,我有jsonpath,它告诉我获取某些值。如果要获取子元素的值,则需要获取所有相应的父属性值,并将所有这些值作为一行存储在数据帧中Python 打印嵌套JSON的父数据和子数据,python,json,Python,Json,我有以下类型的JSON。在另一个表中,我有jsonpath,它告诉我获取某些值。如果要获取子元素的值,则需要获取所有相应的父属性值,并将所有这些值作为一行存储在数据帧中 { "Parent": { "Name": "Bob", "Age": "80", "Children": [ { "Name": "Michael", "Gender":"M", "Children": [ {
{
"Parent": {
"Name": "Bob",
"Age": "80",
"Children": [
{
"Name": "Michael",
"Gender":"M",
"Children": [
{
"Name": "Ezee",
"Gender": "M",
"Age": 20
},
{
"Name": "Ezee",
"Gender": "M",
"Age": 28,
"Children": [
{
"Name": "Dre",
"Age": 1
},
{
"Name": "George",
"Age": 2
}
]
}
],
"Age": 50,
"MiddleName": "Jay"
},
{
"Name": "Justin",
"Gender": "M",
"Children": [
{
"Name": "Emily",
"Age": 18,
"Gender": "F"
}
],
"Age": 45
}
]
}
}
假设我需要获取JSON路径的值:Parent/Children/0/Children/0/Name
,我需要获取对应父级(Parent/Children/0/[Name或age或etc.])的Name、age等属性值,并将上述所有值存储为一行
{
"Parent": {
"Name": "Bob",
"Age": "80",
"Children": [
{
"Name": "Michael",
"Gender":"M",
"Children": [
{
"Name": "Ezee",
"Gender": "M",
"Age": 20
},
{
"Name": "Ezee",
"Gender": "M",
"Age": 28,
"Children": [
{
"Name": "Dre",
"Age": 1
},
{
"Name": "George",
"Age": 2
}
]
}
],
"Age": 50,
"MiddleName": "Jay"
},
{
"Name": "Justin",
"Gender": "M",
"Children": [
{
"Name": "Emily",
"Age": 18,
"Gender": "F"
}
],
"Age": 45
}
]
}
}
目前,我可以通过传递相关路径分别获取父值,通过传递该路径分别获取子值
def findValue(path, json_data):
paths = path.split("/")
data = json_data
for i in range(0,len(paths)):
if isinstance(data, list):
paths[i]=int(paths[i])
data = data[paths[i]]
else:
data = data.get(paths[i])
return data
我怎样才能做到这一点呢?如果我理解得很好,您所需要的只是一个路径,如
Parent/Children/0/Children/0/Name
获取其父属性的相同路径。在这种情况下,它将是Parent/Children/0/Name
下面是我对python解释器的尝试,希望它能帮助您:
>>> path = "Parent/Children/0/Children/0/Name"
>>> path_l = path.split('/')
>>> rev = path_l[::-1]
>>> rev
['Name', '0', 'Children', '0', 'Children', 'Parent']
>>> rev.index('Children')
2
>>> rev = rev[rev.index('Children')+1:]
>>> rev
['0', 'Children', 'Parent']
>>> final = rev[::-1] + [path_l[-1]]
>>> final
['Parent', 'Children', '0', 'Name']
>>> parent_path = '/'.join(final)
>>> parent_path
'Parent/Children/0/Name'
然后使用您的函数,您可以将两个值添加到数据帧中
>>> df = pandas.DataFrame({'Parent': [], 'Children':[]})
>>> df.append([parent], [children])
如果我理解得很好,那么您所需要的只是一个路径,如
Parent/Children/0/Children/0/Name
get其父属性的相同路径。在这种情况下,它将是Parent/Children/0/Name
下面是我对python解释器的尝试,希望它能帮助您:
>>> path = "Parent/Children/0/Children/0/Name"
>>> path_l = path.split('/')
>>> rev = path_l[::-1]
>>> rev
['Name', '0', 'Children', '0', 'Children', 'Parent']
>>> rev.index('Children')
2
>>> rev = rev[rev.index('Children')+1:]
>>> rev
['0', 'Children', 'Parent']
>>> final = rev[::-1] + [path_l[-1]]
>>> final
['Parent', 'Children', '0', 'Name']
>>> parent_path = '/'.join(final)
>>> parent_path
'Parent/Children/0/Name'
然后使用您的函数,您可以将两个值添加到数据帧中
>>> df = pandas.DataFrame({'Parent': [], 'Children':[]})
>>> df.append([parent], [children])
要获取最后一个父级,您需要遍历路径,直到最后一次跟随
子级
列表
例如,给定路径:'Parent/Children/0/Children/0/Name'
您希望在'Parent/Children/0'
处返回父级的数据
这在Python中很容易做到,只需将路径
字符串切分到子字符串的最后一个匹配项/Children
:
path[:path.rfind('/Children')]
然后,您可以使用与当前获取父级数据类似的代码:
parent = json_data
path = path[:path.rfind('/Children')]
for attr in path.split('/'):
parent = parent[int(attr) if isinstance(parent, list) else attr]
在本例中,这将为我们提供parent
,如下所示:
{
"Name": "Michael",
"Gender": "M",
"Children": [
{
"Name": "Ezee",
"Gender": "M",
"Age": 20
},
{
"Name": "Ezee",
"Gender": "M",
"Age": 28,
"Children": [
{
"Name": "Dre",
"Age": 1
},
{
"Name": "George",
"Age": 2
}
]
}
],
"Age": 50,
"MiddleName": "Jay"
}
为了完整地完成您的问题,如果您希望此人的属性(没有其子项列表
)作为一行,您必须决定以一种固定的方式(如字母顺序)存储这些属性,然后您可以使用dict的.items()
方法将其提取为正确的格式:
[v for k,v in sorted(t for t in parent.items() if t[0] != 'Children')]
举个例子:
[50, 'M', 'Jay', 'Michael']
#Age, Gender, Middle Name, Name
哦,如果您愿意,第一段代码可以压缩成一行:
__import__('functools').reduce(lambda d,a:d[int(a) if isintance(d,list) else a], path[:path.rfind('/Children')].split('/'), json_data)
要获取最后一个父级,您需要遍历路径,直到最后一次跟随
子级
列表
例如,给定路径:'Parent/Children/0/Children/0/Name'
您希望在'Parent/Children/0'
处返回父级的数据
这在Python中很容易做到,只需将路径
字符串切分到子字符串的最后一个匹配项/Children
:
path[:path.rfind('/Children')]
然后,您可以使用与当前获取父级数据类似的代码:
parent = json_data
path = path[:path.rfind('/Children')]
for attr in path.split('/'):
parent = parent[int(attr) if isinstance(parent, list) else attr]
在本例中,这将为我们提供parent
,如下所示:
{
"Name": "Michael",
"Gender": "M",
"Children": [
{
"Name": "Ezee",
"Gender": "M",
"Age": 20
},
{
"Name": "Ezee",
"Gender": "M",
"Age": 28,
"Children": [
{
"Name": "Dre",
"Age": 1
},
{
"Name": "George",
"Age": 2
}
]
}
],
"Age": 50,
"MiddleName": "Jay"
}
为了完整地完成您的问题,如果您希望此人的属性(没有其子项列表
)作为一行,您必须决定以一种固定的方式(如字母顺序)存储这些属性,然后您可以使用dict的.items()
方法将其提取为正确的格式:
[v for k,v in sorted(t for t in parent.items() if t[0] != 'Children')]
举个例子:
[50, 'M', 'Jay', 'Michael']
#Age, Gender, Middle Name, Name
哦,如果您愿意,第一段代码可以压缩成一行:
__import__('functools').reduce(lambda d,a:d[int(a) if isintance(d,list) else a], path[:path.rfind('/Children')].split('/'), json_data)