Python 无限级分类树状结构生成算法的实现


Posted in Python onJanuary 21, 2021

后端研发的同学对无限级分类肯定映像深刻,当初花了不少时间吧?

无限级分类树状结构的应用场景很多,例如后端研发需要把用户相关权限读取出来并生成树状结构,前端研发拿到权限树之后可以按照结构展示用户有权限访问的栏目;再例如网页上的栏目分级:

Python 无限级分类树状结构生成算法的实现

作者在初次接触树状结构生成需求的时候,也是挠头,后来找到了一个代码少且清晰易懂的生成算法:递归。

首先,确保数据库中存储的类别信息如下:

[
 {"id": 1, "name": '电器', "parent": 0},
 {"id": 2, "name": '水果', "parent": 0},
 {"id": 3, "name": '家用电器', "parent": 1},
 {"id": 4, "name": '电吹风', "parent": 3},
 {"id": 5, "name": '电风扇', "parent": 3},
 {"id": 6, "name": '台灯', "parent": 3},
 {"id": 7, "name": '商用电器', "parent": 1},
 {"id": 8, "name": '大型电热锅', "parent": 7},
]

字段 parent 记录的是此条目的父编号,例如电吹风的父编号是 3,即电吹风属于家用电器,而家用电器的父编号是 1,即家用电器属于电器类产品。电吹风条目跟电器条目并无直接的标识进行关联,但需要用树状结构来表明 电器 <- 家用电器 <- 电吹风 的关系。

通过 parent 寻找父编号,并建立关联关系的操作实际上是循环往复的,直到找完所有的结点,这跟递归算法非常契合,很轻松便能写出对应的递归代码:

def generate_tree(source, parent):
 tree = []
 for item in source:
 if item["parent"] == parent:
 item["child"] = generate_tree(source, item["id"])
 tree.append(item)
 return tree

只需要将数据库中存储的信息传递给 generate_tree 函数即可。这段递归代码在往复循环的过程中通过 parent 来寻找子结点,找到子结点后将其添加到树中。完整代码如下:

import json
def generate_tree(source, parent):
 tree = []
 for item in source:
 if item["parent"] == parent:
 item["child"] = generate_tree(source, item["id"])
 tree.append(item)
 return tree
if __name__ == '__main__':
 permission_source = [
 {"id": 1, "name": '电器', "parent": 0},
 {"id": 2, "name": '水果', "parent": 0},
 {"id": 3, "name": '家用电器', "parent": 1},
 {"id": 4, "name": '电吹风', "parent": 2},
 {"id": 5, "name": '电风扇', "parent": 3},
 {"id": 6, "name": '台灯', "parent": 3},
 {"id": 7, "name": '商用电器', "parent": 1},
 {"id": 8, "name": '大型电热锅', "parent": 7},
 ]
 permission_tree = generate_tree(permission_source, 0)
 print(json.dumps(permission_tree, ensure_ascii=False))

你试试运行一下,看看结构是否符合预期。

使用缓存优化算法

递归算法中有很多重复的计算,这些计算不仅占用额外资源,还会降低函数执行效率,因此需要对递归进行优化。这里选用缓存优化法提升函数执行效率。

基本思路是每次找到结点关系后将此条目的编号添加到一个列表中缓存起来,代表此条目已找到结点关系。当往复循环执行函数时再次遇到此条目可以跳过。代码改动很简单,增加一个缓存列表和控制流语句即可:

def generate_tree(source, parent, cache=[]):
 tree = []
 for item in source:
 if item["id"] in cache:
 continue
 if item["parent"] == parent:
 cache.append(item["id"])
 item["child"] = generate_tree(source, item["id"], cache)
 tree.append(item)
 return tree

至此,无限级分类树状结构生成算法完成。你学会了吗?

到此这篇关于Python 无限级分类树状结构生成算法的实现的文章就介绍到这了,更多相关Python 无限级分类树状结构内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用sorted函数对列表进行排序的方法
Apr 04 Python
python清除指定目录内所有文件中script的方法
Jun 30 Python
Python3 批量扫描端口的例子
Jul 25 Python
softmax及python实现过程解析
Sep 30 Python
如何在VSCode上轻松舒适的配置Python的方法步骤
Oct 28 Python
opencv之为图像添加边界的方法示例
Dec 26 Python
新年福利来一波之Python轻松集齐五福(demo)
Jan 20 Python
Python MySQL 日期时间格式化作为参数的操作
Mar 02 Python
PyQt5实现登录页面
May 30 Python
Python爬虫如何破解JS加密的Cookie
Nov 19 Python
python des,aes,rsa加解密的实现
Jan 16 Python
解决pytorch 保存模型遇到的问题
Mar 03 Python
python 制作网站筛选工具(附源码)
Jan 21 #Python
python使用scapy模块实现ping扫描的过程详解
Jan 21 #Python
Python 中如何使用 virtualenv 管理虚拟环境
Jan 21 #Python
python使用scapy模块实现ARP扫描的过程
Jan 21 #Python
Python3利用scapy局域网实现自动多线程arp扫描功能
Jan 21 #Python
Pandas直接读取sql脚本的方法
Jan 21 #Python
python asyncio 协程库的使用
Jan 21 #Python
You might like
77A一级收信机修理记
2021/03/02 无线电
转PHP手册及PHP编程标准
2006/12/17 PHP
使用PHP下载CSS文件中的图片的代码
2013/09/24 PHP
php比较两个绝对时间的大小
2014/01/31 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
PHP判断文件是否被引入的方法get_included_files用法示例
2016/11/29 PHP
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
2013/12/17 Javascript
jquery.validate.js插件使用经验记录
2014/07/02 Javascript
javascript实现简单的二级联动
2015/03/19 Javascript
浅谈Javascript的静态属性和原型属性
2015/05/07 Javascript
浅谈js的html元素的父节点,子节点
2016/08/06 Javascript
jquery的checkbox,radio,select等方法小结
2016/08/30 Javascript
利用Angularjs实现幻灯片效果
2016/09/07 Javascript
JavaScript实现动态增删表格的方法
2017/03/09 Javascript
浅谈react+es6+webpack的基础配置
2017/08/09 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
layui 富文本图片上传接口与普通按钮 文件上传接口的例子
2019/09/23 Javascript
vue-form表单验证是否为空值的实例详解
2019/10/29 Javascript
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
Python实现windows下模拟按键和鼠标点击的方法
2015/03/13 Python
Python中用Spark模块的使用教程
2015/04/13 Python
python 保存float类型的小数的位数方法
2018/10/17 Python
python读取csv和txt数据转换成向量的实例
2019/02/12 Python
Django文件存储 自己定制存储系统解析
2019/08/02 Python
python3 pathlib库Path类方法总结
2019/12/26 Python
python rsa-oaep加密的示例代码
2020/09/23 Python
使用phonegap进行提示操作的具体方法
2017/03/30 HTML / CSS
哈萨克斯坦最大的时装、鞋子和配饰在线商店:Lamoda.kz
2019/11/19 全球购物
描述RIP和OSPF区别以及特点
2015/01/17 面试题
检查接待方案
2014/02/27 职场文书
运动员获奖感言
2014/08/15 职场文书
新学期主题班会
2015/08/17 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技