Python - 将家族树信息序列化为JSON的递归函数

时间:2015-10-05 11:40:37

标签: python json recursion tree

我在创建一个以JSON格式生成族谱的函数时遇到了困难。

这里可以看到一个双亲,两个后代树的例子:

{
    "children": [
        {
            "id": 409,
            "name": "Joe Bloggs",
            "no_parent": "true"
        },
        {
            "children": [
                {
                    "children": [],
                    "id": 411,
                    "name": "Alice Bloggs"
                },
                {
                    "children": [],
                    "id": 412,
                    "name": "John Bloggs"
                }
            ],
            "hidden": "true",
            "id": "empty_node_id_9",
            "name": "",
            "no_parent": "true"
        },
        {
            "children": [],
            "id": 410,
            "name": "Sarah Smith",
            "no_parent": "true"
        }
    ],
    "hidden": "true",
    "id": "year0",
    "name": ""
}

Joe Bloggs与Sarah Smith结婚,其中有孩子Alice Bloggs和John Bloggs。空节点纯粹用于处理树形图中的顶点(参见下面的jsfiddle)。 上面的例子应该有助于解释语法。在这个jsfiddle上可以找到一个更复杂的树:http://jsfiddle.net/cyril123/0vbtvoon/22/ 与jsfiddle关联的JSON可以从第34行到第101行找到。

我在编写一个递归生成族树的JSON的函数时遇到了困难。我从一个person类开始,该类代表该家族中最老的成员。然后该函数将检查婚姻,子女等,并继续直到树完成,返回json。

我的代码涉及person类以及相关的marriage类。我有适当的方法,如每个人的id,get_marriage()函数,get_children()方法等。我想知道最好的方法是这样做。

我可以在下面找到我对递归函数的尝试。涉及的方法/功能等不详细,但其目的应该是不言自明的。非常感谢。

def root_nodes(people, first_node=False): #begin by passing in oldest family member and first_node=True
    global obj, current_obj, people_used
    if obj is not None: print len(str(obj))
    if type(people) != list: 
        people = [people]
    for x in people:
        if x in rootPeople and first_node: #handles the beginning of the JSON with an empty 'root' starting node.
            first_node = False
            obj = {'name': "", 'id': 'year0', 'hidden': 'true', 'children': root_nodes(people)}
            return obj
        else:
            marriage_info = get_marriage(x)
            if marriage_info is None: #if person is not married
                current_obj = {'name': x.get_name(), 'id': x.get_id(), 'children': []}
                people_used.append(x)
            else: 
                partners = marriage_info.get_members()
                husband, wife = partners[0].get_name(), partners[1].get_name()
                husband_id, wife_id = marriage_info.husband.get_id(), marriage_info.wife.get_id()
                marriage_year = marriage_info.year
                children = marriage_info.get_children()
                people_used.append(partners[0])
                people_used.append(partners[1])
                if partners[0].get_parents() == ['None', 'None'] or partners[1].get_parents() == ['None', 'None']:
                    if partners[0].get_parents() == ['None', 'None'] and partners[1].get_parents() == ['None', 'None']:
                        current_obj = {'name': str(husband), 'id': husband_id, 'no_parent': 'true'}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'no_parent': 'true', 'children': []}               
                    if partners[0].get_parents() == ['None', 'None'] and partners[1].get_parents() != ['None', 'None']:
                        current_obj = {'name': str(husband), 'id': husband_id, 'no_parent': 'true'}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'children': []}
                    if partners[0].get_parents() != ['None', 'None'] and partners[1].get_parents() == ['None', 'None']:
                        current_obj = {'name': str(husband), 'id': husband_id}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'no_parent': 'true', 'children': []}              
                else:
                    if not any((True for x in partners[0].get_parents() if x in people_used)):
                        current_obj = {'name': str(husband), 'id': husband_id, 'no_parent' : 'true'}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'children': []}
                    elif not any((True for x in partners[1].get_parents() if x in people_used)):
                        current_obj = {'name': str(husband), 'id': husband_id}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'no_parent': 'true', 'children': []}
                    else:
                        current_obj = {'name': str(husband), 'id': husband_id}, {'name': '', 'id': 'empty_node_id_' + empty_node(), 'no_parent': 'true', 'hidden': 'true', 'children': root_nodes(children)}, {'name': str(wife), 'id': wife_id, 'children': []}
                return current_obj
            if obj is None:
                obj = current_obj
            else: 
                obj = obj, current_obj
            if people.index(x) == len(people)-1:
                return obj

即使上面的函数编写得很糟糕 - 它几乎是成功的。它失败的唯一例子是如果一个孩子结婚,那么其他孩子就会错过JSON。这是因为返回obj而未进入for loop中的下一次迭代。关于如何解决这个问题的任何建议都将不胜感激。

0 个答案:

没有答案