根据两个列表中指定的规则创建字典词典

时间:2020-04-23 23:58:14

标签: python

我正在做一个练习,该练习涉及查找树结构的高度,其中树是根据两个列表中指定的规则构建的。

我已经找到了可以成功找到高度的解决方案。但是,在寻找一种用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:{}}}}

有人可以提出一种动态的解决方案来创建字典吗,该解决方案可以从与上述类似的其他列表中构建?

我尝试使用递归对此进行解决,但是一直失败。

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使用字符串而不是数字来更好地区分索引和值