为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

杨魅力 2022-09-20 16:57:57
我想将字典的嵌套列表转换为子结构。并找到一种强大的方法来做到这一点。结构: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"  },] 到:{  "vehicle": {    "car": {        "sedan" : {}     }  },  "fruit" : {     "apple": {},    "grape": {},    "pineapple": {}  }}请注意,在这种情况下,它可以向下两级。但它也可以在三个深处。例如,一个附加条目:{    "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它在这种情况下有效。问题是它不够健壮。我正在考虑递归,但无法破解它。有人可以帮忙吗?谢谢
查看完整描述

2 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

溶液

您可以使用 和 :collections.defaultdictdict.setdefault


from collections import defaultdict


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"

    },

]


working_dict = defaultdict(dict)

result_dict = {}


for item in nested_list:

    name = item['name']

    if 'id' in item:

        id_ = item['id']

        working_dict[id_].setdefault(name, working_dict[name])

    else:

        result_dict[name] = working_dict[name]

print(working_dict)

print(result_dict)

输出:


defaultdict(<class 'dict'>, {'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'apple': {}, 'grape': {}, 'pineapple': {}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}, 'car': {'sedan': {'mini sedan': {}}}, 'sedan': {'mini sedan': {}}, 'mini sedan': {}})

{'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}}

解释

  • 这个想法:是可变的。dict

  • working_dict是所有 s 的参考表。"id"

  • 如果没有这样的ID,请注册。{}

  • 并注册没有字段的元素,作为根元素进入.idresult_dict


附加

如果不想使用 ,则只能使用 。但它更冗长。collections.defaultdictdict.setdefault

working_dict = {}

result_dict = {}


for item in nested_list:

    name = item['name']

    if 'id' in item:

        id_ = item['id']

        working_dict.setdefault(id_, {}).setdefault(name, working_dict.setdefault(name, {}))

    else:

        result_dict[name] = working_dict.setdefault(name, {})

print(result_dict)


查看完整回答
反对 回复 2022-09-20
?
湖上湖

TA贡献2003条经验 获得超2个赞

您也可以使用递归函数手动执行此操作。理念:

  • 循环访问输入列表中的元素

  • 忽略不带键的元素id

  • 对于带有 in 键的元素:id

    • 在输出中递归搜索此键

    • 添加 元素(如果元素已经存在,则元素将添加到递归函数中,否则在之后)。

# 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': {}

#         }

#     }

# }


查看完整回答
反对 回复 2022-09-20
  • 2 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号