Python 将嵌套字典转换为列表
我知道这里有很多问题需要列出,但我找不到我的情况所需要的信息,所以我要问一个新问题 一些背景:我正在为我的模型使用一个分层包,并且生成树结构的内置函数输出一个嵌套循环,以指示父对象、子对象等。我的目标是在视图中保留逻辑并输出一个列表,以便我可以在模板中简单地循环它 这是我的数据,在树结构中:Python 将嵌套字典转换为列表,python,django,django-templates,django-views,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>: { <
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)
我需要做什么才能更深入
谢谢 我认为递归可以成为你的朋友:
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)
top={”“:{”“:{”“:{},”:{},“:{”“:{},”:{”“:{},“:{},”:{}
儿童(父亲):
本地_列表=[]
对于键,父项中的值。iteritems()
本地\u列表。追加(键)
本地列表。扩展(抓取子项(值))
返回本地列表
打印抓取子对象(顶部)
开始。。。呃,我是说,递归。试试这个:
def recurse(dict):
result = []
for key in dict:
result.append(key)
result.extend(recurse(dict[key]))
return result
这个问题不能通过简单的字典迭代来解决。您需要一种称为
def getKeys(D,答案):
如果不是D:
返回
其他:
对于D中的k:
答案.附加(k)
getKeys(D[k],答案)
如果名称=“\uuuuu main\uuuuuuuu”:
d={”“:{”“:{”“:{}},”:{},“:{”“:{},”:{”“:{},“:{},”:{}
答案=[]
获取密钥(d,答案)
打印答案
这已经过测试,并正在发挥作用
希望这对您有所帮助基于Mihai的回答:您需要对密钥进行排序,否则您可能会遇到问题:
def recurse(d):
result = []
for key in sorted(d.keys()):
result.append(key)
result.extend(recurse(d[key]))
return result
以前的所有解决方案都递归地构建大量列表,然后将它们扩展回越来越大的列表,直到得到最终答案。虽然它可以工作,但从性能的角度来看,它并不是最优的,因为它创建了许多您确实不需要的列表,并且需要将相同的项目多次扩展到它们的父列表中。有些解决方案还忘记按键排序
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)
top={”“:{”“:{”“:{},”:{},“:{”“:{},”:{”“:{},“:{},”:{}
def展平(d,ret=无):
如果ret为无:
ret=[]
对于k,v在已排序的(d.items())中:
ret.append(k)
如果v:
展平(v、ret)
回程网
def test():
展平(顶部)
根据
python-m timeit-s“import flatte”“flatte.test()”
,此方法在更新以正确排序输出时,每个循环使用8.57个usecs,而对于Cédrics answer,每个循环使用14.4个usecs(对于键,排序中的值(父项()):
)我在shell中这样做,它返回了几百个值,而不是10个?我错过了什么吗?结果是错误的,因为'Part:1.3'
没有出现在末尾。而且它执行的次数越多,它就会不断添加到自身中。它对我来说很好。也许您意外地将result
声明为全局?我不知道我第一次做了什么,但它确实工作得很好for
循环将只执行一次迭代,因为它包含一个返回。这也不是一个好主意……是的,这次回归并不是最好的一次。它现在已修复,尽管结果是错误的,因为'Part:1.3'
没有出现在末尾。在第5行中获取一个KeyError用于
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)