创建分层JSON对象的递归函数?
Posted
技术标签:
【中文标题】创建分层JSON对象的递归函数?【英文标题】:Recursive function to create hierarchical JSON object? 【发布时间】:2012-05-31 00:35:00 【问题描述】:我只是不够优秀的计算机科学家,无法自己解决这个问题:(
我有一个返回 JSON 响应的 API,如下所示:
// call to /api/get/200
id : 200, name : 'France', childNode: [ id: 400, id: 500]
// call to /api/get/400
id : 400, name : 'Paris', childNode: [ id: 882, id: 417]
// call to /api/get/500
id : 500, name : 'Lyon', childNode: [ id: 998, id: 104]
// etc
我想递归解析它并构建一个看起来像这样的分层 JSON 对象:
id: 200,
name: 'France',
children: [
id: 400,
name: 'Paris',
children: [...]
,
id: 500,
name: 'Lyon',
children: [...]
],
到目前为止,我有这个,它会解析树的每个节点,但不会将其保存到 JSON 对象中。如何扩展它以将其保存到 JSON 对象中?
hierarchy =
def get_child_nodes(node_id):
request = urllib2.Request(ROOT_URL + node_id)
response = json.loads(urllib2.urlopen(request).read())
for childnode in response['childNode']:
temp_obj =
temp_obj['id'] = childnode['id']
temp_obj['name'] = childnode['name']
children = get_child_nodes(temp_obj['id'])
// How to save temp_obj into the hierarchy?
get_child_nodes(ROOT_NODE)
这不是作业,但也许我需要做一些作业才能更好地解决这类问题:(谢谢你的帮助。
【问题讨论】:
children的children是否包含id或object? 对象列表,因此层次结构一直向下延伸到叶节点。 在你的代码中这不应该是response['name']
而不是childnode['name']
吗?
@Jan-PhilipGehrcke - 是的,应该。目前没有存储根节点,我已经意识到。
为什么问题和答案中包含来自 urllib2 的请求?是因为处理的数据在网站上吗?
【参考方案1】:
def get_node(node_id):
request = urllib2.Request(ROOT_URL + node_id)
response = json.loads(urllib2.urlopen(request).read())
temp_obj =
temp_obj['id'] = response['id']
temp_obj['name'] = response['name']
temp_obj['children'] = [get_node(child['id']) for child in response['childNode']]
return temp_obj
hierarchy = get_node(ROOT_NODE)
【讨论】:
【参考方案2】:你可以使用这个(更紧凑和可读的版本)
def get_child_nodes(node_id):
request = urllib2.Request(ROOT_URL + node_id)
response = json.loads(urllib2.urlopen(request).read())
return
"id":response['id'],
"name":response['name'],
"children":map(lambda childId: get_child_nodes(childId), response['childNode'])
get_child_nodes(ROOT_NODE)
【讨论】:
【参考方案3】:您不会从对递归函数的每次调用中返回任何内容。因此,您似乎只想在循环的每次迭代中将每个 temp_obj
字典附加到一个列表中,并在循环结束后返回它。比如:
def get_child_nodes(node_id):
request = urllib2.Request(ROOT_URL + node_id)
response = json.loads(urllib2.urlopen(request).read())
nodes = []
for childnode in response['childNode']:
temp_obj =
temp_obj['id'] = childnode['id']
temp_obj['name'] = childnode['name']
temp_obj['children'] = get_child_nodes(temp_obj['id'])
nodes.append(temp_obj)
return nodes
my_json_obj = json.dumps(get_child_nodes(ROOT_ID))
(顺便说一句,请注意不要混用制表符和空格,因为 Python 对此不太宽容。最好只使用空格。)
【讨论】:
您将如何从该列表中创建所需的层次结构?目标是拥有一组嵌套的字典,然后是json.dumps()
ed。
我的代码怎么没有提供呢?每个递归都形成自己的字典,然后返回给父级。
对不起,丹尼尔。我误读了所需的结构和您的代码。【参考方案4】:
今天下午我遇到了同样的问题,最后重新调整了我在网上找到的一些代码。
我已将代码上传到 Github (https://github.com/abmohan/objectjson) 和 PyPi (https://pypi.python.org/pypi/objectjson/0.1),包名为“objectjson”。下面也是:
代码 (objectjson.py)
import json
class ObjectJSON:
def __init__(self, json_data):
self.json_data = ""
if isinstance(json_data, str):
json_data = json.loads(json_data)
self.json_data = json_data
elif isinstance(json_data, dict):
self.json_data = json_data
def __getattr__(self, key):
if key in self.json_data:
if isinstance(self.json_data[key], (list, dict)):
return ObjectJSON(self.json_data[key])
else:
return self.json_data[key]
else:
raise Exception('There is no json_data[\'key\'].'.format(key=key))
def __repr__(self):
out = self.__dict__
return '%r' % (out['json_data'])
使用示例
from objectjson import ObjectJSON
json_str = ' "test": "a":1,"b": "c":3 '
json_obj = ObjectJSON(json_str)
print(json_obj) # 'test': 'b': 'c': 3, 'a': 1
print(json_obj.test) # 'b': 'c': 3, 'a': 1
print(json_obj.test.a) # 1
print(json_obj.test.b.c) # 3
【讨论】:
【参考方案5】:免责声明:我不知道 json 是什么,所以您可能需要弄清楚如何用您的语言正确编写它:p。如果我的示例中的伪代码太伪,请随时询问更多细节。
你需要在某个地方返回一些东西。如果您从未在递归调用中返回某些内容,则无法获取对新对象的引用并将其存储在您调用递归的对象中。
def getChildNodes (node) returns [array of childNodes]
data = getData(fromServer(forThisNode))
new childNodes array
for child in data :
new temp_obj
temp_obj.stores(child.interestingStuff)
for grandchild in getChildNodes(child) :
temp_obj.arrayOfchildren.append(grandchild)
array.append(temp_obj)
return array
或者,如果您的语言支持,您可以使用迭代器而不是返回。
【讨论】:
以上是关于创建分层JSON对象的递归函数?的主要内容,如果未能解决你的问题,请参考以下文章