我想要做的是获得每个元素的等级。
我目前正在使用此代码:
re = {0: [b.keys()[0]]}
n = 1
for a in b:
l = []
for e in s[a]:
l.append(e)
if l != []:
re.update({n: l})
n += 1
print re
这给了我以下输出:
{"0": ["a"], "1": ["b"], "2": ["i"], "3": ["c", "d"], "4": ["f", "g", "h"], "5": ["e", "l"]}
我在这里做错了什么?
答案 0 :(得分:4)
这里有一些问题:
[s.keys()[0]]
作为查找树的“根”的方法。但请注意,字典是无序的(CPython-3.6字典中的是使用插入顺序,但这被视为实现细节),因此无法保证[s.keys()[0]]
实际上是根;和所以我们需要解决这两个问题。第一个可以通过查找不是另一个元素的子节点来解决。所以我们可以把它写成:
nonroots = {c for cs in s.values() for c in cs}
这些都是子节点,因此这意味着字典中不在子节点中的所有键都是根:
roots = [k for k in s if k not in nonroots]
根位于0
级别,因此我们可以将其设置为:
levels[0] = roots
现在,对于每次迭代,我们通过查找与前一次迭代相对应的值来构造下一代。
next_gen = [c for k in prev_gen for c in s.get(k,())]
所以现在我们可以把它变成一个循环:只要前一代包含至少一个元素,我们就会继续构建新一代。所以完整的实现是:
nonroots = {c for cs in s.values() for c in cs}
level = [k for k in s if k not in nonroots]
generation = 0
result = {}
while level:
result[generation] = level
generation += 1
level = [c for k in level for c in s.get(k,())]
最后,result
是一个将所有级别映射到子级列表的字典。
请注意,我们最好使用列表而不是字典,因为代数从索引0
开始,我们知道如果有一代 i ,那么也有一代 i-1 (对于 i> 0 )。所以我们可以把它变成如下列表:
nonroots = {c for cs in s.values() for c in cs}
level = [k for k in s if k not in nonroots]
result = []
while level:
result.append(level)
level = [c for k in level for c in s.get(k,())]
这给了我们:
>>> result
[['a'], ['b'], ['c', 'd'], ['i', 'e', 'l'], ['f', 'g', 'h']]
我们还可以使用调用者提供根的方法,在这种情况下,我们生成一个树。我们可以改变现有方法,例如:
def get_levels(tree, roots):
result = []
roots = list(roots)
while roots:
result.append(roots)
roots = [c for k in roots for c in tree.get(k,())]
return result
现在我们可以用给定的根列表来调用它。如果根不是真正的根,我们将获得给定树下的子树的排序:
>>> get_levels(s, ['a'])
[['a'], ['b'], ['c', 'd'], ['i', 'e', 'l'], ['f', 'g', 'h']]
>>> get_levels(s, ['c'])
[['c'], ['i']]
>>> get_levels(s, ['i','l'])
[['i', 'l']]
>>> get_levels(s, ['i','e'])
[['i', 'e'], ['f', 'g', 'h']]