我正在做一个练习,该练习涉及查找树结构的高度,其中树是根据两个列表中指定的规则构建的。
我已经找到了可以成功找到高度的解决方案。但是,在寻找一种用python构建树的方法时,我不得不手动创建树。
本质上,我想创建一个动态解决方案来构建遵循树形结构的字典的字典。
可以从两个列表中获得构建字典的规则,如下所示:
a = [0,1,2,3,4]
b = [4,-1,4,1,1]
列出a是字典键值
列表b指定b中的键在字典层次结构中的位置
规则
我们可以从列表b中-1的位置获取字典的根密钥。 在列表b中,值-1在索引1处。因此,根键是列表a(1)中在索引1处的值:
dic [1] = {}
可以通过在列表b中找到根键(1)的实例索引来获得层次结构中的下一个键。 由于根键是1,而1在列表b中的索引3和4处,因此下一个键将在列表a(3&4)的索引3和4中:
dic [1] [3]
dic [1] [4]
通过在列表b中查找键3和4,可以以相同的方式获得层次结构中的下一个键。由于键4位于列表b中的索引0和索引2处,因此下一个键将位于列表a中的索引0和索引2中(值0和2),并且它们将位于层次结构中的键4下:
dic [1] [4] [0]
dic [1] [4] [2]
由于3没有出现在列表b中,因此它将仅包含一个空字典。
最后,我们将有以下字典:
dic = {1:{3:{},4:{0:{},2:{}}}}
有人可以提出一种动态的解决方案来创建字典吗,该解决方案可以从与上述类似的其他列表中构建?
我尝试使用递归对此进行解决,但是一直失败。
答案 0 :(得分:1)
因此,我打开了一个ipython会话并开始弄乱。显然,a和b是相关的,所以我将它们压缩为list(zip(a,b))。由于b是层次结构,而a是字典的键,因此我将它们反转为list(zip(b,a))。由于-1很特殊,我想对它进行排序,sorted(zip(b,a))。这看起来很接近我们想要的内容,但是我们不知道会有多少重复,因此我将其更改为字典,可能有更好的代码,但是我做到了。
d = {k:[i for i,j in zip(a,b) if k==j] for k in set(b)}
现在,我们实际上可以看到如何构造字典。例如,d [-1]返回[1],因此d [-1] [0]将成为下一个级别的键,因此我们将d [d [-1] [0]]进行计算下一组键。它将像d [d [d [d [-1] [0]] [1]]一样继续。因此,看起来我们需要一个递归函数,该函数可以连续访问此字典,如果键不存在,则返回一个空字典。像这样:
d = {k:[i for i,j in zip(a,b) if k==j] for k in set(b)}
def f(k):
return {i:f(i) for i in d.get(k,{})}
answer = f(-1)
没有尝试简化此代码。
答案 1 :(得分:0)
您可以使用中间链接字典并单次通过父子关系来构建字典:
a = ["0","1","2","3","4"]
b = [4,-1,4,1,1]
links = { key:{} for key in a }
tree = links[None] = dict()
for child,parent in enumerate(b):
childKey = a[child]
parentKey = None if parent < 0 else a[parent]
links[parentKey].update({childKey:links[childKey]})
输出:
print(tree)
# {'1': {'3': {}, '4': {'0': {}, '2': {}}}}
注意:我为a
使用字符串而不是数字来更好地区分索引和值