Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,如果节点位于树的深处,如何分配节点的子节点?_Python_Json - Fatal编程技术网

在Python中,如果节点位于树的深处,如何分配节点的子节点?

在Python中,如果节点位于树的深处,如何分配节点的子节点?,python,json,Python,Json,我有描述树(父-子)的数据。我想在此基础上构建一个JSON文件,并在树中找到父级的任何位置分配父级的子级 这个问题是这个答案的延伸: 代码: file = [ ('parent1', ['child1', 'child2', 'child3']), ('parent2', ['child4', 'child5', 'child6']), ('child1', ['child7', 'child8']), ('child5', ['child10', 'c

我有描述树(父-子)的数据。我想在此基础上构建一个JSON文件,并在树中找到父级的任何位置分配父级的子级

这个问题是这个答案的延伸:

代码:

file = [
     ('parent1', ['child1', 'child2', 'child3']),
     ('parent2', ['child4', 'child5', 'child6']),
     ('child1', ['child7', 'child8']),
     ('child5', ['child10', 'child33']),
     ('parent3', ['child1', 'child2', 'child3'])
]

json_dict = {}
flat_dict = {}

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = {}
        flat_dict[parent] = json_dict[parent] = value
    for child in children:
        flat_dict[child] = value[child] = {}
{
    "parent1": {
        "child1": {
            "child7": {},
            "child8": {}
        },
        "child2": {},
        "child3": {}
    },
    "child1": {},
    "child2": {},
    "child3": {},
    "parent2": {
        "child4": {},
        "child5": {
            "child10": {},
            "child33": {}
        },
        "child6": {}
    },
    "child4": {},
    "child5": {
        "child10": {},
        "child33": {}
    },
    "child6": {},
    "child7": {},
    "child8": {},
    "child10": {},
    "child33": {},
    "parent3": {
        "child1": {},
        "child2": {},
        "child3": {}
    }
}
{'parent1': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}, 'parent2': {'child4': {}, 'child5': {'child10': {}, 'child33': {}}, 'child6': {}}, 'parent3': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}}
电流输出:

file = [
     ('parent1', ['child1', 'child2', 'child3']),
     ('parent2', ['child4', 'child5', 'child6']),
     ('child1', ['child7', 'child8']),
     ('child5', ['child10', 'child33']),
     ('parent3', ['child1', 'child2', 'child3'])
]

json_dict = {}
flat_dict = {}

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = {}
        flat_dict[parent] = json_dict[parent] = value
    for child in children:
        flat_dict[child] = value[child] = {}
{
    "parent1": {
        "child1": {
            "child7": {},
            "child8": {}
        },
        "child2": {},
        "child3": {}
    },
    "child1": {},
    "child2": {},
    "child3": {},
    "parent2": {
        "child4": {},
        "child5": {
            "child10": {},
            "child33": {}
        },
        "child6": {}
    },
    "child4": {},
    "child5": {
        "child10": {},
        "child33": {}
    },
    "child6": {},
    "child7": {},
    "child8": {},
    "child10": {},
    "child33": {},
    "parent3": {
        "child1": {},
        "child2": {},
        "child3": {}
    }
}
{'parent1': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}, 'parent2': {'child4': {}, 'child5': {'child10': {}, 'child33': {}}, 'child6': {}}, 'parent3': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}}
预期输出:

我希望所有
child1
节点如下:

"child1": {
    "child7": {},
    "child8": {}
}

但正如我们所看到的,只有在
parent1
节点中,它才保留其子节点。

希望这是您想要的

代码

relations = []
for k,l in file:
    for v in l:
        relations.append((k,v))
pop_list=[]
items = {}
for parent, child in relations:
    parent_dict = items.setdefault(parent, {})
    child_dict = items.setdefault(child, {})
    if child not in parent_dict:
        parent_dict[child] = child_dict
    pop_list.append(child)
for child in pop_list:
    if child in items.keys():
        items.pop(child)
print(items)

输出:

file = [
     ('parent1', ['child1', 'child2', 'child3']),
     ('parent2', ['child4', 'child5', 'child6']),
     ('child1', ['child7', 'child8']),
     ('child5', ['child10', 'child33']),
     ('parent3', ['child1', 'child2', 'child3'])
]

json_dict = {}
flat_dict = {}

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = {}
        flat_dict[parent] = json_dict[parent] = value
    for child in children:
        flat_dict[child] = value[child] = {}
{
    "parent1": {
        "child1": {
            "child7": {},
            "child8": {}
        },
        "child2": {},
        "child3": {}
    },
    "child1": {},
    "child2": {},
    "child3": {},
    "parent2": {
        "child4": {},
        "child5": {
            "child10": {},
            "child33": {}
        },
        "child6": {}
    },
    "child4": {},
    "child5": {
        "child10": {},
        "child33": {}
    },
    "child6": {},
    "child7": {},
    "child8": {},
    "child10": {},
    "child33": {},
    "parent3": {
        "child1": {},
        "child2": {},
        "child3": {}
    }
}
{'parent1': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}, 'parent2': {'child4': {}, 'child5': {'child10': {}, 'child33': {}}, 'child6': {}}, 'parent3': {'child1': {'child7': {}, 'child8': {}}, 'child2': {}, 'child3': {}}}

一种方法是对链接的答案添加一个简单的修改,检查是否已经存在子项,并使用现有的对象

json_dict = {}
flat_dict = {}

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = {}
        flat_dict[parent] = json_dict[parent] = value
    for child in children:
        if child in flat_dict:
            value[child] = flat_dict[child]
        else:
            flat_dict[child] = value[child] = {}
在这两种情况下,代码都可以通过使用来缩短,但我通常不会使用,因为它会创建一个空字典实例,即使这不是必需的:

json_dict = {}
flat_dict = {}

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = json_dict[parent] = flat_dict[parent] = {}
    for child in children:
        value[child] = flat_dict.setdefault(child, {})
虽然第二个解决方案执行一些可能不必要的操作,但代码看起来更清晰

同样干净但不必要对象较少的替代方案使用:

除了需要导入外,此解决方案的打印效果不如基于常规dict的解决方案干净。但是,这不会以任何方式影响到JSON的转换

由于您评论说实际上不希望在根中包含子节点,因此此处显示的代码段将仅将父节点放置在根中。但是,如果您稍后发现某个节点是子节点,则它们不会从根节点中删除该节点。这可以通过另一个简单的修改来实现,这里显示的是
defaultdict
示例,但也适用于所有其他示例:

from collections import defaultdict

json_dict = {}
flat_dict = defaultdict(dict)

for parent, children in file:
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = json_dict[parent] = flat_dict[parent]
    for child in children:
        value[child] = flat_dict[child]
        json_dict.pop(child, None)
下面是一个有最终答案的例子

请记住,此代码不会检查循环引用。循环引用将自动从结果中删除自身。例如:

file = [
    ('A', ['B']),
    ('B', ['C']),
    ('C', ['A']),
]

所以你不想要父节点?实际上我需要所有的。我需要保留在树中任何位置找到的任何节点的子节点。您确定这些节点始终命名为父节点和子节点吗?有一个很简单的问题,你可能在这里错过了,伙计。我只是把他们命名为家长和孩子,以便澄清,否则他们都有一个特定的ID。我注意到你有很多问题,人们已经回答了,但你没有选择任何答案。当答案满足您的需要时,您应该单击它旁边的复选标记。这会给所有相关人员打分,更重要的是,将您的问题从未回答的队列中删除。您只能选择一个答案,但可以对所有答案进行投票。非常感谢您提供的解决方案和解释。一切似乎都很好,两个答案都很好。但是在运行了更多的测试之后,当我添加这些数据时,您的代码中没有一个可以绕过该测试:('child9',[]),('child8',['child9','B','C'])。问题是,当根节点“child9”以后成为子节点时,它不会被其他代码删除。在上一段代码中,您提到了这种情况,它删除了它,但它会将其他子节点带到根节点。e、 g.“儿童2”和“儿童5”。但所有这些可能性都与@lazycoder解决方案有关。@jesy2013。谢谢你接电话。我已经对我的代码做了一些修复。我试图在不考虑后果的情况下缩短代码。应该不会再有丢失的角落箱子了。谢谢你。这也是一个很好的简短解决方案。