python递归查询菜单并转换成json实例

yizhihongxing

对于这个问题,我们来逐步分析。

一、递归查询菜单

假设我们有如下的菜单数据:

[
    {"id": 1, "name": "菜单1", "parent_id": None},
    {"id": 2, "name": "菜单2", "parent_id": None},
    {"id": 3, "name": "菜单3", "parent_id": 1},
    {"id": 4, "name": "菜单4", "parent_id": 1},
    {"id": 5, "name": "菜单5", "parent_id": 2},
    {"id": 6, "name": "菜单6", "parent_id": 4},
    {"id": 7, "name": "菜单7", "parent_id": 6},
    {"id": 8, "name": "菜单8", "parent_id": 5}
]

通过递归查询菜单,我们希望得到以下结果:

菜单1
├── 菜单3
└── 菜单4
    └── 菜单6
        └── 菜单7
菜单2
└── 菜单5
    └── 菜单8

我们可以使用如下的 Python 代码来实现递归查询菜单:

def get_menu_children(menu, parent_id=None):
    children = []
    for item in menu:
        if item['parent_id'] == parent_id:
            item_children = get_menu_children(menu, item['id'])
            if item_children:
                item['children'] = item_children
            children.append(item)
    return children

在上述代码中,我们通过遍历菜单,将所有 parent_id 为指定值的项目作为当前 item 的子菜单添加进去。由于可能存在多层子菜单,因此对所有子菜单也递归调用这个函数,直到找到所有子菜单。

示例代码:

menu_data = [
    {"id": 1, "name": "菜单1", "parent_id": None},
    {"id": 2, "name": "菜单2", "parent_id": None},
    {"id": 3, "name": "菜单3", "parent_id": 1},
    {"id": 4, "name": "菜单4", "parent_id": 1},
    {"id": 5, "name": "菜单5", "parent_id": 2},
    {"id": 6, "name": "菜单6", "parent_id": 4},
    {"id": 7, "name": "菜单7", "parent_id": 6},
    {"id": 8, "name": "菜单8", "parent_id": 5}
]

menu_tree = get_menu_children(menu_data)
for item in menu_tree:
    print(item['name'])
    if 'children' in item:
        for child in item['children']:
            print("  ├──", child['name'])
            if 'children' in child:
                for sub_child in child['children']:
                    print("  │   └──", sub_child['name'])

二、转换成Json实例

接下来,我们把上述菜单数据转换成 Json 实例。转换过程如下:

def menu_to_json(menu):
    res = []
    for item in menu:
        res.append({
            "id": item['id'],
            "name": item['name'],
        })
        if 'children' in item:
            res[-1]['children'] = menu_to_json(item['children'])
    return res

在上述代码中,我们通过遍历菜单,把每个 item 转化为 Json 语法,包含 idname,并根据是否含有子菜单来判断是否要添加 children 项。

这样,我们就得到了如下的 Json 实例:

[
    {
        "id":1,
        "name":"菜单1",
        "children":[
            {
                "id":3,
                "name":"菜单3"
            },
            {
                "id":4,
                "name":"菜单4",
                "children":[
                    {
                        "id":6,
                        "name":"菜单6",
                        "children":[
                            {
                                "id":7,
                                "name":"菜单7"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id":2,
        "name":"菜单2",
        "children":[
            {
                "id":5,
                "name":"菜单5",
                "children":[
                    {
                        "id":8,
                        "name":"菜单8"
                    }
                ]
            }
        ]
    }
]

另外,我们可以把 Python 字典转换成 Json,如下所示:

import json

menu_dict = menu_to_json(menu_data)
menu_json = json.dumps(menu_dict, ensure_ascii=False, indent=4)
print(menu_json)

输出结果:

[
    {
        "id": 1,
        "name": "菜单1",
        "children": [
            {
                "id": 3,
                "name": "菜单3"
            },
            {
                "id": 4,
                "name": "菜单4",
                "children": [
                    {
                        "id": 6,
                        "name": "菜单6",
                        "children": [
                            {
                                "id": 7,
                                "name": "菜单7"
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id": 2,
        "name": "菜单2",
        "children": [
            {
                "id": 5,
                "name": "菜单5",
                "children": [
                    {
                        "id": 8,
                        "name": "菜单8"
                    }
                ]
            }
        ]
    }
]

三、示例说明

以上就是 Python 递归查询菜单并转换成 Json 实例的代码实现过程。下面提供两个示例。

示例1

假设我们需要从一个有多层嵌套的分类树中取出一条分类链上的所有分类节点及其所有的子节点,并按照节点在分类层级链中的顺序,转换成 Json,如下所示:

category_data = [
    {"id": 1, "name": "电器", "parent_id": None},
    {"id": 2, "name": "手机", "parent_id": 1},
    {"id": 3, "name": "笔记本电脑", "parent_id": 1},
    {"id": 4, "name": "智能电视", "parent_id": 1},
    {"id": 5, "name": "苹果", "parent_id": 2},
    {"id": 6, "name": "三星", "parent_id": 2},
    {"id": 7, "name": "戴尔", "parent_id": 3},
    {"id": 8, "name": "联想", "parent_id": 3},
    {"id": 9, "name": "小米", "parent_id": 2},
    {"id": 10, "name": "夏普", "parent_id": 4}
]

def get_category_chain(category, chain=None):
    if chain is None:
        chain = []
    chain.insert(0, {"id": category["id"], "name": category["name"]})
    if category["parent_id"]:
        parent_category = next((item for item in category_data if item["id"] == category["parent_id"]), None)
        if parent_category:
            get_category_chain(parent_category, chain)
    return chain

category_id = 8
category = next((item for item in category_data if item["id"] == category_id), None)
category_chain = get_category_chain(category)

category_dict = [menu_to_json(category_chain)]
print(json.dumps(category_dict, ensure_ascii=False, indent=4))

输出结果:

[
    [
        {
            "id": 1,
            "name": "电器",
            "children": [
                {
                    "id": 3,
                    "name": "笔记本电脑",
                    "children": [
                        {
                            "id": 7,
                            "name": "戴尔"
                        },
                        {
                            "id": 8,
                            "name": "联想"
                        }
                    ]
                },
                {
                    "id": 4,
                    "name": "智能电视",
                    "children": [
                        {
                            "id": 10,
                            "name": "夏普"
                        }
                    ]
                },
                {
                    "id": 2,
                    "name": "手机",
                    "children": [
                        {
                            "id": 5,
                            "name": "苹果"
                        },
                        {
                            "id": 9,
                            "name": "小米"
                        },
                        {
                            "id": 6,
                            "name": "三星"
                        }
                    ]
                }
            ]
        },
        {
            "id": 3,
            "name": "笔记本电脑",
            "children": [
                {
                    "id": 7,
                    "name": "戴尔"
                },
                {
                    "id": 8,
                    "name": "联想"
                }
            ]
        },
        {
            "id": 8,
            "name": "联想"
        }
    ]
]

示例2

假设我们有一个课程目录,包含多个课程分类和课程。我们需要按照分类的结构,把课程目录转换成树形结构,并转换成 Json 数据,输出到文件中。示例如下:

class_item_data = [
    {"id": 1, "name": "课程分类1", "parent_id": None},
    {"id": 2, "name": "课程1", "parent_id": 1},
    {"id": 3, "name": "课程2", "parent_id": 1},
    {"id": 4, "name": "课程分类2", "parent_id": None},
    {"id": 5, "name": "课程3", "parent_id": 4},
    {"id": 6, "name": "课程分类1-1", "parent_id": 1},
    {"id": 7, "name": "课程4", "parent_id": 6},
    {"id": 8, "name": "课程分类1-2", "parent_id": 1},
    {"id": 9, "name": "课程5", "parent_id": 8},
    {"id": 10, "name": "课程分类2-1", "parent_id": 4},
    {"id": 11, "name": "课程6", "parent_id": 10},
    {"id": 12, "name": "课程分类2-2", "parent_id": 4},
    {"id": 13, "name": "课程7", "parent_id": 12}
]

class_item_tree = get_menu_children(class_item_data)

class_dict = menu_to_json(class_item_tree)
with open("class_tree.json", 'w', encoding='utf-8') as f:
    f.write(json.dumps(class_dict, ensure_ascii=False, indent=4))

输出结果:使用任意的 JSON 解析工具打开class_tree.json可以看到详细的JSON结构体现了实际的树形结构。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python递归查询菜单并转换成json实例 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • Pandas中Replace函数使用那些事儿

    Pandas库是一个数据处理、数据分析的强大工具,其中replace函数常常被用来对数据进行替换操作。下面是Pandas中replace函数的详细使用攻略。 replace函数的语法 replace函数语法如下: DataFrame.replace(self, to_replace=None, value=None, inplace=False, limit…

    python 2023年5月14日
    00
  • 在Pandas中对数据框架的浮动列进行格式化

    在Pandas中对数据框架的浮动列进行格式化,可以使用applymap()函数和Styler类。 首先,我们创建一个数据框架: import pandas as pd import numpy as np data = pd.DataFrame(np.random.rand(5, 5), columns=[‘A’, ‘B’, ‘C’, ‘D’, ‘E’]) …

    python-answer 2023年3月27日
    00
  • 快速解释如何使用pandas的inplace参数的使用

    当调用Pandas 的许多更改操作时,您通常有两个选项:直接更改现有 DataFrame 或 Series 对象,或者返回新的更改副本。使用 inplace 参数可以使更改直接应用于现有对象,而无需创建新副本。本文将详细介绍 Pandas 中 inplace 参数的使用方法及示例。 什么是 inplace 参数? inplace 参数是许多 Pandas 操…

    python 2023年5月14日
    00
  • pandas实现按行选择的示例代码

    以下是pandas实现按行选择的详细攻略: 1. 数据准备 在学习pandas之前,需要准备一些数据。这里我们以一个名为students.csv的csv文件为例,其中包含学生的姓名、年龄和成绩三列数据。可以使用以下代码读取csv文件并将其转化为pandas的DataFrame类型: import pandas as pd df = pd.read_csv(‘…

    python 2023年5月14日
    00
  • 如何在Pandas数据框架中删除有NaN值的行

    在 Pandas 数据框架中,要删除包含 NaN 值的行,可以使用 dropna() 方法。该方法默认删除任何包含至少一个 NaN 数据的行。同时,还可以通过一些参数来进一步控制删除行的条件。 下面是一个完整的实例,演示如何使用 dropna() 方法删除包含 NaN 值的行: import pandas as pd import numpy as np #…

    python-answer 2023年3月27日
    00
  • Python 绘制桑基图全面解析

    Python 绘制桑基图全面解析 桑基图(Sankey Diagram),也称桑基能量平衡图、桑基能流图,用于显示元素之间的流动。在此,我将向您介绍如何使用Python绘制桑基图的方法。 安装matplotlib库 在进行桑基图绘制之前,我们首先需要安装Matplotlib库,它是Python中广泛使用的绘图库。 您可以在命令行中使用下面的命令进行安装: p…

    python 2023年6月13日
    00
  • python 两种方法修改文件的创建时间、修改时间、访问时间

    下面是关于Python修改文件的创建时间、修改时间和访问时间的攻略: 1. Python中的os.path模块 Python中的os.path模块提供了一系列函数,可用于获取或修改文件的元数据,包括文件大小、创建时间、修改时间和访问时间等。其中,os.path.getmtime()函数可用于获取文件的修改时间,os.path.getctime()函数可用于获…

    python 2023年5月14日
    00
  • Python绘制组合图的示例

    下面是Python绘制组合图的完整攻略: 1. 确定数据 在绘制组合图之前,我们需要先确定需要展示的数据。以绘制折线图和柱状图的组合图为例,我们可以选择以下两组数据: 折线图数据 月份 销售额 1月 500 2月 700 3月 900 4月 1200 5月 1500 6月 1800 柱状图数据 月份 成本 1月 300 2月 400 3月 500 4月 65…

    python 2023年6月13日
    00
合作推广
合作推广
分享本页
返回顶部