将嵌套字典转换为列表

时间:2011-05-09 14:15:26

标签: python django django-templates django-views

我知道有很多词典可以在这里列出问题,但我找不到我需要的信息,所以我要问一个新的问题。

一些背景:我正在为我的模型使用分层包,并且生成树结构的内置函数输出一个嵌套循环来指示父母,孩子等。我的目标是将逻辑保持在视图和输出中一个列表,以便我可以在我的模板中简单地循环它。

这是我的数据,在树形结构中:

1
-1.1
--1.1.1
---1.1.1.1
--1.1.2
-1.2
--1.2.1
--1.2.2
-1.3

这是我得到的嵌套词典

{
 <Part: 1.1>:
 {
   <Part: 1.1.1>:
     {
       <Part: 1.1.1.1>: {}
     }, 
   <Part: 1.1.2>: {}
 },
 <Part: 1.2>: 
 {
   <Part: 1.2.1>: {},
   <Part: 1.2.2>: {}
 }, 
 <Part: 1.3>: {}
}

或者如果你不喜欢我试图分解它的方式,这就是我在一行中得到的:

{<Part: 1.1>: {<Part: 1.1.1>: {<Part: 1.1.1.1>: {}}, <Part: 1.1.2>: {}}, <Part: 1.2>: {<Part: 1.2.1>: {}, <Part: 1.2.2>: {}}, <Part: 1.3>: {}}

我想要的是:

[<Part: 1.1>, <Part: 1.1.1>, <Part: 1.1.1.1>, <Part: 1.1.2>, <Part: 1.2>, <Part: 1.2.2>, <Part: 1.2.1>, <Part: 1.3>,]

我试过迭代dict.items中的键,但后来我只得到顶级键(1.1,1.2,1.3)

我需要做些什么才能更深入?

谢谢!

5 个答案:

答案 0 :(得分:10)

我认为递归可以成为你的朋友:

top = {"<Part: 1.1>": {"<Part: 1.1.1>": {"<Part: 1.1.1.1>": {}}, "<Part: 1.1.2>": {}}, "<Part: 1.2>": {"<Part: 1.2.1>": {}, "<Part: 1.2.2>": {}}, "<Part: 1.3>": {}}

 def grab_children(father):
    local_list = []
    for key, value in father.iteritems():
        local_list.append(key)
        local_list.extend(grab_children(value))
    return local_list

print grab_children(top)

答案 1 :(得分:2)

所有以前的解决方案都会递归地构建大量列表,然后将它们扩展回更大更大的列表,直到您得到最终答案。虽然它有效但从性能角度来看并不是最佳的,因为它创建了许多您真正不需要的列表,并涉及将相同的项目多次扩展到其父列表中。有些解决方案也忘了按键排序。

top = {"<Part: 1.1>": {"<Part: 1.1.1>": {"<Part: 1.1.1.1>": {}}, "<Part: 1.1.2>": {}}, "<Part: 1.2>": {"<Part: 1.2.1>": {}, "<Part: 1.2.2>": {}}, "<Part: 1.3>": {}}

def flatten(d, ret=None):
    if ret is None:
        ret = []
    for k, v in sorted(d.items()):
        ret.append(k)
        if v:
            flatten(v, ret)
    return ret

def test():
    flatten(top)

根据python -m timeit -s "import flatten" "flatten.test()",此方法每个循环使用8.57个usecs,而Cédrics答案每个循环使用14.4个usecs,更新时也正确排序输出(for key, value in sorted(father.items()):

答案 2 :(得分:1)

成立......呃,我的意思是,递归。试试这个:

def recurse(dict):
    result = []
    for key in dict:
        result.append(key)
        result.extend(recurse(dict[key]))
    return result

答案 3 :(得分:0)

通过字典上的简单迭代无法解决此问题。您需要一种名为recursive descent

的算法
def getKeys(D, answer):
    if not D:
        return
    else:
        for k in D:
            answer.append(k)
            getKeys(D[k], answer)

if __name__ == "__main__":
    d = {"<Part: 1.1>": {"<Part: 1.1.1>": {"<Part: 1.1.1.1>": {}}, "<Part: 1.1.2>": {}}, "<Part: 1.2>": {"<Part: 1.2.1>": {}, "<Part: 1.2.2>": {}}, "<Part: 1.3>": {}}
    answer = []
    getKeys(d, answer)
    print answer

这已经过测试并且正在运行

希望这有帮助

答案 4 :(得分:0)

根据Mihai的回答:您需要对键进行排序,否则您可能会遇到问题:

def recurse(d):
    result = []
    for key in sorted(d.keys()):
        result.append(key)
        result.extend(recurse(d[key]))
    return result