从 python 中的节点列表构建完整路径
Build full paths from list of nodes in python
我有一本包含 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
处理此问题的最佳 pythonic 方法是什么?
我已经尝试 binarytree
并且我可以构建树但无法创建完整路径。
如果你有一个 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")
有差异的版本
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)
一种更通用的递归方法 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']
我有一本包含 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
处理此问题的最佳 pythonic 方法是什么?
我已经尝试 binarytree
并且我可以构建树但无法创建完整路径。
如果你有一个 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")
有差异的版本
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)
一种更通用的递归方法 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']