简体   繁体   中英

How to find all the paths to a particular node to leaf node and also the preceding nodes from python dictionary?

I have a list of dictionary fname ( fname serves as the key), parent and child node associated with each node (dictionary reference in code). I will input one key (For following piece of code B is the key- ie fname : ['B'] ). I have to keep parent node into consideration. For BI want paths as [A,B,C,C1,X],[A,B,C,C2],[A,B,D,D1],[A,B,D,D2],[R1,B,C,C1,X],[R,B,C,C2],[R1,B,D,D1],[R2,B,D,D2],[R1,B,P] .

I tried to find the leaf nodes, but i am not getting any output for the following piece of code.

def neighbor_find(graph, key, neighbor, current_path, paths_list):
    for v in range(0,len(graph)-1):  #access the values in list 
        if d[v]['fname'] == key: #checks if the key input is present in the list
            if not d[v][neighbor]: #if not the path is appended as it is
                paths_list.append(current_path)
            else: # if key present in list, checks its parent/child 
                for node in d[v][neighbor]:
                    for i in range(0,len(d[v]['parent'])):
                        print(d[v]['parent'][i]['name'])
                    neighbor_find(graph, node, neighbor, [node] + current_path, paths_list)


def path_find(graph, key, path_list):
    parents_list, children_list = [], []
    neighbor_find(graph, key, 'parent', [], parents_list) 
    neighbor_find(graph, key, 'child', [], children_list)

    for parent_path in parents_list:
        for children_path in children_list:
            path_list.append(parent_path + [key] + children_path[::-1])
    for i in range (0,len(path_list)):
        print("path" ,i+1 , ":", path_list[i])


d = [
     {
          'file' : 'user_auth.py',
          'fname': 'B',
          'parent': [{'name': 'A','filename': 'user_auth.py'},{'name': 'R1','filename': 'user_registration.py'}],
          'child': [{'name': ['C', 'D'], 'filename' : 'user_auth.py'}],
          'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']        
     },
     { 'file' : 'user_auth.py',
         'fname': 'C',
         'parent': [{'name': ['B', 'M'], 'filename': 'user_auth.py'}],
         'child': [{'name':['C1', 'C2'], 'filename' : 'user_auth.py' }],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_004']
     },
      { 'file' : 'user_auth.py',
        'fname': 'D',
         'parent': [{'name': 'B' , 'filename' : 'user_auth.py'}],
         'child': [{'name':['D1', 'D2'], 'filename' : 'user_auth.py' }],
         'tags': ['TC_HRM_API_002','TC_HRM_UI_002']
      },
     { 'file' : 'out.js',
        'fname': 'C1',
         'parent': [{'name':'C', 'filename' : 'user_auth.py'}],
         'child': [{'name': 'X', 'filename' : 'user_auth.py'}],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
     },
      { 'file' : 'user_auth.py',
        'fname': 'M',
         'parent': [],
         'child': [{'name': 'C', 'filename'  : 'user_auth.py'} , { 'name' : 'N' , 'filename' : 'user_registration.py'}],
         'tags': ['TC_HRM_API_001','TC_HRM_API_001','TC_HRM_UI_003']
      },
     { 'file' : 'user_auth.py',
        'fname': 'A',
         'parent': [],
         'child': [{'name': 'B', 'filename'  : 'user_auth.py'}],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_005']
      },
      {'file' : 'user_registration.py',
        'fname': 'N',
         'parent': [{'name': 'M', 'filename'  : 'user_auth.py'}],
         'child': [],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
      },
      {'file' : 'user_auth.py',
        'fname': 'D1',
         'parent': [{'name': 'D', 'filename'  : 'user_auth.py'} ],
         'child': [],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
         },
      { 'file' : 'user_auth.py',
        'fname': 'D2',
         'parent': [{'name': 'D', 'filename'  : 'user_auth.py'}],
         'child': [],
         'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
     },
      { 'file' : 'user_auth.py',
          'fname': 'C2',
          'parent': [{'name': 'C', 'filename'  : 'user_auth.py'} ],
          'child': [],
          'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
      },
      { 'file': 'user_auth.py',
       'fname': 'X',
          'parent': [{'name': 'C1', 'filename'  : 'user_auth.py'} ],
          'child': [],
          'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
      },
     { 'file' : 'user_auth.py',
           'fname' :  'B',
           'parent' : [{'name': 'R1', 'filename'  : 'user_registration.py'} ],
           'child' : [{'name': 'P', 'filename'  : 'user_auth.py'} ],
           'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
            },
     { 'file' : 'user_registration.py',
          'fname' : 'R1',
           'parent' : [],
           'child' : [{'name': 'B', 'filename'  : 'user_auth.py'} ],
           'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
            },
     { 'file' : 'user_auth.py',
          'fname' : 'P',
           'parent' : [{'name': 'B', 'filename'  : 'user_auth.py'} ],
           'child' : [],
           'tags': ['TC_HRM_API_001','TC_HRM_API_002','TC_HRM_UI_003']
            }]

key = 'B'

path_list = []
path_find(d, key, path_list)

Expected output is : [A,B,C,C1,X],[A,B,C,C2],[A,B,D,D1],[A,B,D,D2],[R1,B,C,C1,X],[R,B,C,C2],[R1,B,D,D1],[R2,B,D,D2],[R1,B,P] actual output is: []

we can split this problem into:

  1. find all the paths from current node to parent (root)
  2. find all the paths from current node to child (leaf)
  3. concat all parents paths and chilren paths together like product .

So the main problem in your code is that you only traverse the children, you can try the idea above by dfs :

def neighbor_find(graph, key, neighbor, current_path, paths_list):
    for v in graph.values():
        if v['fname'] == [key]:
            if not v[neighbor]:
                paths_list.append(current_path)
            else:
                for node in v[neighbor]:
                    neighbor_find(graph, node, neighbor, [node] + current_path, paths_list)


def path_find(graph, key, path_list):
    parents_list, children_list = [], []
    neighbor_find(graph, key, 'parent', [], parents_list)
    neighbor_find(graph, key, 'child', [], children_list)

    for parent_path in parents_list:
        for children_path in children_list:
            path_list.append(parent_path + [key] + children_path[::-1])

test code:

d = {1: {'fname': ['B'],
         'parent': ['A'],
         'child': ['C', 'D']},
     2: {'fname': ['C'],
         'parent': ['B', 'M'],
         'child': ['C1', 'C2']},
     3: {'fname': ['D'],
         'parent': ['B'],
         'child': ['D1', 'D2']},
     4: {'fname': ['C1'],
         'parent': ['C'],
         'child': ['X']},
     5: {'fname': ['M'],
         'parent': [],
         'child': ['C', 'N']},
     6: {'fname': ['A'],
         'parent': [],
         'child': ['B']},
     7: {'fname': ['N'],
         'parent': ['M'],
         'child': []},
     8: {'fname': ['D1'],
         'parent': ['D'],
         'child': []},
     9: {'fname': ['D2'],
         'parent': ['D'],
         'child': []},
     10: {'fname': ['C2'],
          'parent': ['C'],
          'child': []},
     11: {'fname': ['X'],
          'parent': ['C'],
          'child': []},
     }
key = 'C'

path_list = []
path_find(d, key, path_list)

print(path_list)

output:

[['A', 'B', 'C', 'C1', 'X'], ['A', 'B', 'C', 'C2'], ['M', 'C', 'C1', 'X'], ['M', 'C', 'C2']]

Hope that helps you, and comment if you have further questions. : )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM