Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中转换字典的嵌套列表_Python_List_Dictionary - Fatal编程技术网

在Python中转换字典的嵌套列表

在Python中转换字典的嵌套列表,python,list,dictionary,Python,List,Dictionary,我想将嵌套字典列表转换为子结构。并找到一种强有力的方法来实现这一目标。结构: nested_list = [ { "id" : "fruit", "name" : "apple" }, { "name": "fruit" }, { "id" : "fruit", "name" : "grape" }, { "id" : "fruit", "name" : "pineapple" }, {

我想将嵌套字典列表转换为子结构。并找到一种强有力的方法来实现这一目标。结构:

nested_list = [
  {
     "id" : "fruit",
     "name" : "apple"
  },
  {
     "name": "fruit"
  },
  {
     "id" : "fruit",
     "name" : "grape"
  },
  {
     "id" : "fruit",
     "name" : "pineapple"
  },
  {
     "name": "vehicle"
  },
  {
    "id" : "vehicle",
     "name": "car"
  },
  {
    "id" : "car",
     "name": "sedan"
  },
] 
进入:

注意,在这种情况下,它可以下降两级。但它也可以深入三层。例如,一个附加条目:

{ 
   "id" : "sedan", 
   "name": "mini sedan" 
}
到目前为止,我的做法是:

for category in nested_list:
    if 'id' not in category:
        d[category['name']] = {}

for category in nested_list:
    if 'id' in category and category['id'] in d:
        d[category['id']][category['name']] = {}
    elif 'id' in category and category['id'] not in d:
        for k, v in d.items():
            if category['id'] in v:
                d[k][category['id']] = {category['name']: {}}
    # If there are not top level key then do nothing
    else:
        pass
它在这种情况下起作用。问题是它不够健壮。我在考虑递归,但无法破解它。有人能帮忙吗?谢谢

解决方案 您可以使用
collections.defaultdict
dict.setdefault

从集合导入defaultdict
嵌套列表=[
{
“id”:“水果”,
“名称”:“苹果”
},
{
“名称”:“水果”
},
{
“id”:“水果”,
“名称”:“葡萄”
},
{
“id”:“水果”,
“名称”:“菠萝”
},
{
“名称”:“车辆”
},
{
“id”:“车辆”,
“名称”:“汽车”
},
{
“id”:“汽车”,
“名称”:“轿车”
},
{
“id”:“轿车”,
“名称”:“迷你轿车”
},
]
工作目录=默认目录(目录)
结果_dict={}
对于嵌套列表中的项目:
名称=项目['name']
如果项目中有“id”:
id=项目['id']
工作指令[id].setdefault(名称,工作指令[name])
其他:
结果记录[名称]=工作记录[名称]
打印(工作指令)
打印(结果记录)
输出:

defaultdict(,{'fruit':{'apple':{},{'grape':{},{},{'spineapple':{},{'grape':{},{'spineapple':{},{'vehicle':{'sedan':{},{'mini sedan':{},{'sedan mini sedan':{},{'mini sedan
{'水果':{'苹果':{},'葡萄':{},'菠萝':{},'车辆':{'汽车':{'轿车':{'迷你轿车':{}}

解释
  • 思想:
    dict
    是可变的
  • 工作目录
    是所有
    id
    的参考表
  • 如果没有这样的id,请为其注册
    {}
  • 并将没有
    id
    字段的元素作为根元素注册到
    result\u dict

追加 如果不想使用
collections.defaultdict
,则只能使用
dict.setdefault
。但它更冗长

working_dict={}
结果_dict={}
对于嵌套列表中的项目:
名称=项目['name']
如果项目中有“id”:
id=项目['id']
working_dict.setdefault(id_,{}).setdefault(name,working_dict.setdefault(name,{}))
其他:
result_dict[name]=working_dict.setdefault(name,{})
打印(结果记录)

您还可以使用递归函数手动执行此操作。这个想法:

  • 迭代输入列表中的元素
  • 忽略不带
    id
    键的元素
  • 对于键中具有
    id
    的元素:
    • 在输出中递归搜索此键
    • 添加元素(如果元素已经存在,则在递归函数中添加元素,否则在之后添加)

嗨,当你说“嵌套列表”时,这是故意的吗?您提供的列表不是嵌套的。它包含同一级别的词典。哦,我错了。它不是嵌套列表。而是一个奇怪的层次结构你能分享一个有问题的输入的例子吗?有问题的输入?第一个列表是潜在的输入。我用了一个转换函数来返回输出,就像第二个字典一样,这很好。我认为使用defaultdict也是如此。但是我想要一个类似的答案:{'fruit':{'apple':{},'grape':{},'spineapple':{},'vehicle':{'car':{'sedan':{'mini sedan':{}}
result_dict
就是这样。哇,太神奇了。非常感谢你。我只是想知道有没有一种方法可以让常规代码这样做?如果没有,或者花太多时间,那很好,我不明白常规代码的意思。你能解释更多吗?那意味着不使用defaultdict
for category in nested_list:
    if 'id' not in category:
        d[category['name']] = {}

for category in nested_list:
    if 'id' in category and category['id'] in d:
        d[category['id']][category['name']] = {}
    elif 'id' in category and category['id'] not in d:
        for k, v in d.items():
            if category['id'] in v:
                d[k][category['id']] = {category['name']: {}}
    # If there are not top level key then do nothing
    else:
        pass
# Recursive search
def iterdictAdd(d, id, name):
    # For all element in the dict
    for k, v in d.items():
        # If key match -> add
        if k == id:
            d[id] = {**d[id], **{name: {}}}
            return True
        else:
            # Recursive call
            if isinstance(v, dict):
                if iterdictAdd(v, id, name):
                    return True
    return False


out = {}
# Iterate all dict
for dict_ in nested_list:
    # Ignore elements without "id" 
    if "id" in dict_:
        # Search and add this key
        if not iterdictAdd(out, dict_["id"], dict_["name"]):
            out[dict_["id"]] = {dict_["name"]: {}}

print(out)
# {'fruit': {
#     'apple': {},
#     'grape': {},
#     'pineapple': {}
# },
#  'vehicle': {
#     'car': {
#         'sedan': {}
#         }
#     }
# }