Python:父子层次结构的组合

Sar*_*ist 3 python iteration for-loop hierarchy

对于子父关系表(csv),我尝试使用表中的所有数据收集可能的父子关系组合链。我正在尝试解决一个问题,如果存在多个子父级(参见第 3 行和第 4 行),则第二个子父级组合(第 4 行)不包含在迭代中。

数据示例:

孩子,父母

A,B
A,C
B,D
B,C
C,D
Run Code Online (Sandbox Code Playgroud)

预期连锁结果:

D|B|A
D|C|B|A
D|C|A
Run Code Online (Sandbox Code Playgroud)

实际连锁结果:

D|B|A
D|C|A
Run Code Online (Sandbox Code Playgroud)

代码

find= 'A' #The child for which the code should find all possible parent relationships
sequence = ''
with open('testing.csv','r') as f:     #testing.csv = child,parent table (above example)
    for row in f:
        if row.strip().startswith(find):
            parent = row.strip().split(',')[1]
            sequence = parent + '|' + find
            f1 = open('testing.csv','r')
            for row in f1:
                if row.strip().startswith(parent):
                    parent2 = row.strip().split(',')[1]
                    sequence = parent2 + '|' + sequence
                    parent = parent2
        else:
            continue
        print sequence
Run Code Online (Sandbox Code Playgroud)

vik*_*mls 7

你看过吗这篇精彩的文章吗?要真正理解 Python 中的模式,这是必不可少的阅读内容。您的问题可以被认为是一个图形问题 - 查找关系基本上就是查找从子节点到父节点的所有路径。

由于可能存在任意数量的嵌套(child->parent1->parent2...),因此您需要一个递归解决方案来查找所有路径。在你的代码中,你有 2for循环 - 正如您发现的那样,最多只会产生 3 级路径。

下面的代码改编自上面的链接以解决您的问题。功能find_all_paths需要一个图形作为输入。

让我们从您的文件创建图表:

graph = {} # Graph is a dictionary to hold our child-parent relationships.
with open('testing.csv','r') as f:
    for row in f:
        child, parent = row.split(',')
        graph.setdefault(parent, []).append(child)

print graph
Run Code Online (Sandbox Code Playgroud)

对于您的示例,这应该打印:

{'C': ['A', 'B'], 'B': ['A'], 'D': ['B', 'C']}
Run Code Online (Sandbox Code Playgroud)

以下代码直接来自论文:

def find_all_paths(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return [path]

    if not graph.has_key(start):
        return []

    paths = []

    for node in graph[start]:
        if node not in path:
            newpaths = find_all_paths(graph, node, end, path)
            for newpath in newpaths:
                paths.append(newpath)
    return paths

for path in find_all_paths(graph, 'D', 'A'):
    print '|'.join(path)
Run Code Online (Sandbox Code Playgroud)

输出:

D|B|A
D|C|A
D|C|B|A
Run Code Online (Sandbox Code Playgroud)