【问题标题】:Build full paths from list of nodes in python从python中的节点列表构建完整路径
【发布时间】:2021-10-16 08:48:15
【问题描述】:

我有一本包含 2 个列表的字典。

{'depth': [0, 1, 1, 2, 3, 3, 3, 1, 1, 2, 3], 'nodeName': ['root', 'Deleted Customers', 'New Customers', 'Region', 'Europe', 'Asia', 'America', 'Deleted Partners', 'New Partners', 'Region', 'Europe']}

我需要根据python中的列表构建完整路径。

root\Deleted Customers
root\New Customers\Region\Europe
root\New Customers\Region\Asia
root\New Customers\Region\America
root\Deleted Partners
root\New Partners\Region\Europe

root
├── Deleted Customers
│
└── New Customers
   │
   └── Region
        |── Europe
        ├── Asia
        └── America

处理此问题的最佳 Python 方法是什么? 我尝试了binarytree,我可以构建树,但无法创建完整路径。

【问题讨论】:

  • 这是怎么一棵二叉树?节点 Region 有 3 个子节点。

标签: python list dictionary path tree


【解决方案1】:

一种更通用的递归方法和itertools.groupby

from itertools import groupby as gb
data = {'depth': [0, 1, 1, 2, 3, 3, 3, 1, 1, 2, 3], 'nodeName': ['root', 'Deleted Customers', 'New Customers', 'Region', 'Europe', 'Asia', 'America', 'Deleted Partners', 'New Partners', 'Region', 'Europe']}
def to_tree(n, vals):
    r = []
    for a, b in gb(vals, key=lambda x:x[0] == n):
       if a:
          r.extend([j for _, j in b])
       else:
          r = [*r[:-1], *[r[-1]+'\\'+j for j in to_tree(n+1, b)]]
    yield from r

paths = list(to_tree(0, list(zip(data['depth'], data['nodeName']))))

输出:

['root\\Deleted Customers', 
 'root\\New Customers\\Region\\Europe', 
 'root\\New Customers\\Region\\Asia', 
 'root\\New Customers\\Region\\America', 
 'root\\Deleted Partners', 
 'root\\New Partners\\Region\\Europe']

【讨论】:

  • 谢谢,这就是我想要实现的。我想了解它到底在做什么。你能帮我解决一下 r.extend([j for _, j in b]) 行吗?
  • @Erika r 是从n 生成的路径的运行列表。 r.extend([j for _, j in b]) 正在向 r 添加一组具有相同深度的新路径。 [j for _, j in b] 是一个列表推导式,它根据b 中每个元素的第二个值构建一个列表。 r.extend 获取由推导构建的列表并将每个路径附加到 r
【解决方案2】:

如果您有binarytree,您可以简单地找到从根到该节点的路径。

def hasPath(root, arr, x):
     
    if (not root):
        return False
     
    arr.append(root.data)    

    if (root.data == x):    
        return True
     
    if (hasPath(root.left, arr, x) or
        hasPath(root.right, arr, x)):
        return True
  
    arr.pop(-1)
    return False
 
def printPath(root, x):
     
    # vector to store the path
    arr = []
    
    if (hasPath(root, arr, x)):
        for i in range(len(arr) - 1):
            print(arr[i], end = "/")
        print(arr[len(arr) - 1])
     
    else:
        print("No Path")

【讨论】:

    【解决方案3】:

    有差异的版本

    current_path=['']*4
    paths=[]
    # extend the depth list for the diff
    ext_depth=data['depth']+[data['depth'][-1]]
    # diff will tell what paths you want to print
    diff=list(map(lambda x: x[1]-x[0], zip(ext_depth[1:],ext_depth[:-1])))
    for i, val in enumerate(data['depth']):
        # update path
        current_path[val]=data['nodeName'][i]
        if diff[i]>=0:
            # join only to the proper depth
            paths.append('\\'.join(current_path[:val+1]))
    print(paths)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      相关资源
      最近更新 更多