本文目录导读:

我来详细介绍几种在Python中构建树形数据的常用方法。
使用字典构建树
基础树结构
# 简单的树形字典结构
tree = {
'id': 1,
'name': '根节点',
'children': [
{
'id': 2,
'name': '子节点1',
'children': [
{'id': 4, 'name': '叶子节点1', 'children': []},
{'id': 5, 'name': '叶子节点2', 'children': []}
]
},
{
'id': 3,
'name': '子节点2',
'children': [
{'id': 6, 'name': '叶子节点3', 'children': []}
]
}
]
}
从列表数据构建树
def build_tree_from_list(data, parent_id=None):
"""
从平面数据列表构建树形结构
data: [{'id': 1, 'parent_id': None, 'name': 'root'}, ...]
"""
tree = []
for item in data:
if item['parent_id'] == parent_id:
children = build_tree_from_list(data, item['id'])
if children:
item['children'] = children
else:
item['children'] = []
tree.append(item)
return tree
# 示例数据
flat_data = [
{'id': 1, 'parent_id': None, 'name': '根节点'},
{'id': 2, 'parent_id': 1, 'name': '子节点1'},
{'id': 3, 'parent_id': 1, 'name': '子节点2'},
{'id': 4, 'parent_id': 2, 'name': '叶子节点1'},
{'id': 5, 'parent_id': 2, 'name': '叶子节点2'},
{'id': 6, 'parent_id': 3, 'name': '叶子节点3'}
]
tree = build_tree_from_list(flat_data)
print(tree)
使用类构建树
节点类定义
class TreeNode:
def __init__(self, data):
self.data = data
self.children = []
self.parent = None
def add_child(self, child):
child.parent = self
self.children.append(child)
def get_depth(self):
depth = 0
parent = self.parent
while parent:
depth += 1
parent = parent.parent
return depth
def print_tree(self):
spaces = ' ' * self.get_depth() * 3
prefix = spaces + '|__' if self.parent else ''
print(prefix + self.data)
if self.children:
for child in self.children:
child.print_tree()
# 构建树
root = TreeNode('根节点')
child1 = TreeNode('子节点1')
child2 = TreeNode('子节点2')
root.add_child(child1)
root.add_child(child2)
grandchild1 = TreeNode('叶子节点1')
grandchild2 = TreeNode('叶子节点2')
child1.add_child(grandchild1)
child1.add_child(grandchild2)
root.print_tree()
实际案例:文件系统树
import os
from pathlib import Path
class FileTreeNode:
def __init__(self, path):
self.path = Path(path)
self.name = self.path.name
self.is_dir = self.path.is_dir()
self.children = []
self.size = self.path.stat().st_size if self.path.is_file() else 0
def build(self):
"""递归构建文件树"""
if not self.is_dir:
return self
try:
for item in self.path.iterdir():
node = FileTreeNode(item)
if item.is_dir():
node.build()
self.children.append(node)
except PermissionError:
pass
return self
def print_tree(self, indent=''):
"""打印文件树"""
if self.is_dir:
print(f"{indent}📁 {self.name}/")
new_indent = indent + ' '
for child in self.children:
child.print_tree(new_indent)
else:
size_str = f" ({self.size/1024:.1f}KB)" if self.size > 0 else ""
print(f"{indent}📄 {self.name}{size_str}")
def get_size(self):
"""获取目录总大小"""
if not self.is_dir:
return self.size
return sum(child.get_size() for child in self.children)
# 使用示例
def show_directory_tree(directory_path):
root = FileTreeNode(directory_path)
root.build()
print(f"目录树: {directory_path}")
root.print_tree()
if root.is_dir:
total_size = root.get_size()
print(f"\n总大小: {total_size/1024:.2f} KB")
# 查看当前目录的文件树
show_directory_tree('.')
通用树构建工具
from typing import Any, Dict, List, Optional
class TreeBuilder:
"""通用树构建器"""
@staticmethod
def build_from_parent_id(
items: List[Dict[str, Any]],
id_field: str = 'id',
parent_field: str = 'parent_id',
children_field: str = 'children'
) -> List[Dict[str, Any]]:
"""
从包含parent_id的列表构建树
"""
# 创建id到节点的映射
item_map = {item[id_field]: {**item, children_field: []} for item in items}
tree = []
for item in item_map.values():
parent_id = item.get(parent_field)
if parent_id is None or parent_id not in item_map:
tree.append(item)
else:
item_map[parent_id][children_field].append(item)
return tree
@staticmethod
def flatten_tree(
tree: List[Dict[str, Any]],
children_field: str = 'children'
) -> List[Dict[str, Any]]:
"""将树形结构扁平化"""
flat_list = []
def flatten(node):
node_copy = {k: v for k, v in node.items() if k != children_field}
flat_list.append(node_copy)
for child in node.get(children_field, []):
flatten(child)
for node in tree:
flatten(node)
return flat_list
@staticmethod
def find_node(
tree: List[Dict[str, Any]],
predicate: callable,
children_field: str = 'children'
) -> Optional[Dict[str, Any]]:
"""在树中查找节点"""
for node in tree:
if predicate(node):
return node
if children_field in node:
result = TreeBuilder.find_node(
node[children_field], predicate, children_field
)
if result:
return result
return None
# 使用示例
data = [
{'id': 1, 'parent_id': None, 'name': '研发部'},
{'id': 2, 'parent_id': 1, 'name': '前端组'},
{'id': 3, 'parent_id': 1, 'name': '后端组'},
{'id': 4, 'parent_id': 2, 'name': '张三'},
{'id': 5, 'parent_id': 2, 'name': '李四'},
{'id': 6, 'parent_id': 3, 'name': '王五'}
]
# 构建树
tree = TreeBuilder.build_from_parent_id(data)
print("构建的树:", tree)
# 扁平化
flat = TreeBuilder.flatten_tree(tree)
print("扁平化后:", flat)
# 查找节点
found = TreeBuilder.find_node(tree, lambda n: n['name'] == '张三')
print("查找到的节点:", found)
树的遍历方法
class TreeTraversal:
"""树的遍历方法"""
@staticmethod
def dfs_preorder(node, visit_func):
"""深度优先-前序遍历"""
visit_func(node)
if 'children' in node and node['children']:
for child in node['children']:
TreeTraversal.dfs_preorder(child, visit_func)
@staticmethod
def dfs_postorder(node, visit_func):
"""深度优先-后序遍历"""
if 'children' in node and node['children']:
for child in node['children']:
TreeTraversal.dfs_postorder(child, visit_func)
visit_func(node)
@staticmethod
def bfs(node, visit_func):
"""广度优先遍历"""
queue = [node]
while queue:
current = queue.pop(0)
visit_func(current)
if 'children' in current and current['children']:
queue.extend(current['children'])
# 使用示例
def print_name(node):
print(node['name'])
# 构建简单的树
sample_tree = {
'id': 1, 'name': 'A',
'children': [
{'id': 2, 'name': 'B', 'children': [
{'id': 4, 'name': 'D', 'children': []},
{'id': 5, 'name': 'E', 'children': []}
]},
{'id': 3, 'name': 'C', 'children': [
{'id': 6, 'name': 'F', 'children': []}
]}
]
}
print("前序遍历:")
TreeTraversal.dfs_preorder(sample_tree, print_name)
print("\n后序遍历:")
TreeTraversal.dfs_postorder(sample_tree, print_name)
print("\n广度优先遍历:")
TreeTraversal.bfs(sample_tree, print_name)
推荐使用场景
- 简单的数据展示:使用字典结构
- 需要方法和属性:使用类结构
- 大量数据转换:使用函数式方法
- 文件系统操作:使用Pathlib结合自定义类
- 需要序列化:使用字典结构,方便JSON转换
选择哪种方法取决于你的具体需求,但核心思想都是通过递归来构建和操作树形结构。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播