Python:父子层次的组合 [英] Python: Combinations of parent-child hierarchy

查看:132
本文介绍了Python:父子层次的组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于父子关系表(csv),我试图使用表中的所有数据收集可能的父子关系组合链。如果存在多个子父项(请参阅第3和4行),则第二个子父组合(第4行)不包含在迭代中。 b

数据示例

小孩,父母




$ b $ C




$ b $ C $ b $ C $ b $ C $ b $ C $ b $ C D

预期的连锁结果:
$ b

  D | B | A 
D | C | B | A
D | C | A

实际连锁结果:

< pre class =lang-none prettyprint-override> D | B | A
D | C | A


$ b

代码

  find ='A'#The子代码应该找到所有可能的父关系
sequence =''
with open('testing.csv','r')as f:#testing.csv = child,parent table(above例如)
在f:
中的行如果row.strip()。startswith(find):
parent = row.strip()。split(',')[1]
sequence = parent +'|'+ find
f1 = open('testing.csv','r')
用于f1中的行:
如果row.strip()。startswith(父):
parent2 = row.strip() .blit(',')[1]
sequence = parent2 +'|'+ sequence
parent = parent2
else:
continue
print sequence


解决方案

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



由于可以有任意的数量嵌套(child-> parent1-> parent2 ...),您需要一个递归解决方案来查找所有路径。在你的代码中,对于循环,你有2 - 这只会在你发现的时候导致3级路径。



<下面的代码是根据上面的链接修改你的问题。函数 find_all_paths 需要一个图形作为输入。



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

  graph = { }#图是一个字典来保存我们的孩子 - 父母关系。 
with open('testing.csv','r')as f:
for row in f:
child,parent = row.split(',')
graph .setdefault(parent,[])。append(child)

print graph



<与你的样品,这应该打印:

pre $ {c':['A','B'],'' B':['A'],'D':['B','C']}



<下面的代码是直接的:



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

如果不是graph.has_key(start):
返回[]

路径= []

对于图中的节点[开始]:
如果节点不在路径中:
newpaths = find_all_paths(graph ,node,end,path)
用于newpaths中的newpath:
paths.append(newpath)
返回路径

用于find_all_paths中的路径(graph ,'D','A'):
print'|'.join(path)



< h3>输出:

  D | B | A 
D | C | A
D | C | B | A


For a child-parent relationship table (csv), I am trying to gather possible parent to child relationship combination chains using all data in the table. I am trying against a problem where if multiple sub-parents exist (see rows 3 & 4), the second sub-parent combination (row 4) is not included in the iteration.

Data Example:

child,parent

A,B
A,C
B,D
B,C
C,D

Expected chain results:

D|B|A
D|C|B|A
D|C|A

Actual chain results:

D|B|A
D|C|A

Code

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

解决方案

Have you looked at this fantastic essay? It is essential reading to really understand patterns in python. Your problem can be thought of as a graph problem - finding the relationships is basically finding all paths from a child node to the parent node.

Since there could be an arbitrary amount of nesting (child->parent1->parent2...), you need a recursive solution to find all paths. In your code, you have 2 for loops - which will only result in 3level paths at most as you found out.

The code below was adapted from the link above to fix your issue. The function find_all_paths requires a graph as an input.

Let's create the graph from your file:

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

with your sample, this should print:

{'C': ['A', 'B'], 'B': ['A'], 'D': ['B', 'C']}

The following code is straight from the essay:

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)

Output:

D|B|A
D|C|A
D|C|B|A

这篇关于Python:父子层次的组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆