Python:父子层次结构的组合

Python:父子层次结构的组合,python,for-loop,iteration,hierarchy,Python,For Loop,Iteration,Hierarchy,对于子-父关系表(csv),我尝试使用表中的所有数据收集可能的父-子关系组合链。我试图解决这样一个问题:如果存在多个子父级(请参见第3行和第4行),则迭代中不包括第二个子父级组合(第4行) 数据示例: 孩子,父母 A,B A、 C B、 D B、 C C、 D 预期连锁结果: D|B|A D | C | B | A D | C | A 实际连锁结果: D|B|A D | C | A 代码 find= 'A' #The child for which the code should find

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

数据示例:

孩子,父母

A,B
A、 C
B、 D
B、 C
C、 D
预期连锁结果:

D|B|A
D | C | B | A
D | C | A
实际连锁结果:

D|B|A
D | C | A
代码

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

我不确定这是否是最有效的方法(但在每一行上重新读取文件会更糟糕)

结果:

D|C|A
D|C|B|A
D|B|A
你看过精彩的文章吗?真正理解python中的模式是必要的阅读。您的问题可以看作是一个图形问题—查找关系基本上就是查找从子节点到父节点的所有路径

由于可能存在任意数量的嵌套(child->parent1->parent2…),因此需要一个递归解决方案来查找所有路径。在您的代码中,有2个
for
循环,这将导致您发现的最多3级路径

下面的代码是根据上面的链接改编的,用于修复您的问题。“查找所有路径”功能需要一个图形作为输入

让我们从文件中创建图形:

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
对于您的样本,应打印以下内容:

{'C': ['A', 'B'], 'B': ['A'], 'D': ['B', 'C']}
以下代码直接来自文章:

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)
输出:
我不明白这一点:
我试图解决一个问题,即如果存在多个子父项(见第3行和第4行),第二个子父项组合(第4行)不包括在迭代中
——但您按预期列出了
D | C | B | a
。如果你排除了第四行:B.C对,我认为这个结果不会存在。当前代码不考虑第四行。这正是问题所在。作为一名旁听莎拉,看看你的个人资料,你问了很多问题,人们都回答了。如果有人提供了您认为可以接受的答案,您应该通过单击他们答案旁边的复选标记来接受该答案。到目前为止,您还没有接受任何。谢谢vikramis的文章。这个代码正是我想要的。
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)
D|B|A
D|C|A
D|C|B|A