我正在寻找一款好的树形数据结构类。我发现了这个包,但由于我对Python相对较新(不是编程),我不知道还有没有更好的选择。
我想听听在这里的Python专家们的意见——你们是否有一个经常使用并且可以推荐的树形脚本?
[编辑]
为了澄清,“树”指的是简单的无序树(嗯,这有点递归定义——但希望这样能够澄清问题)。关于我需要树的用途(即用例),我正在从一个扁平文件中读取树状数据,需要从数据建立一棵树并遍历树中的所有节点。
我正在寻找一款好的树形数据结构类。我发现了这个包,但由于我对Python相对较新(不是编程),我不知道还有没有更好的选择。
我想听听在这里的Python专家们的意见——你们是否有一个经常使用并且可以推荐的树形脚本?
[编辑]
为了澄清,“树”指的是简单的无序树(嗯,这有点递归定义——但希望这样能够澄清问题)。关于我需要树的用途(即用例),我正在从一个扁平文件中读取树状数据,需要从数据建立一棵树并遍历树中的所有节点。
import collections
def Tree():
return collections.defaultdict(Tree)
这可能不完全符合您的期望,但它非常有用!对于值的保存仅限于叶节点。以下是其工作原理的示例:
>>> t = Tree()
>>> t
defaultdict(<function tree at 0x2142f50>, {})
>>> t[1] = "value"
>>> t[2][2] = "another value"
>>> t
defaultdict(<function tree at 0x2142f50>, {1: 'value', 2: defaultdict(<function tree at 0x2142f50>, {2: 'another value'})})
更多信息请查看这个要点。
我发现了一个由Brett Alistair Kromkamp编写但未完成的模块。我对其进行了完善,并在Github上公开,将其重命名为treelib
(原名pyTree
):
https://github.com/caesar0301/treelib
希望它能对你有所帮助....
自己动手实现。例如,将树建模为列表的列表。在人们可以提供更好的建议之前,您应该详细说明自己的具体需求。
针对HelloGoodbye的问题,以下是迭代树的示例代码。
def walk(node):
""" iterate tree in pre-order depth-first search order """
yield node
for child in node.children:
for n in walk(child):
yield n
这个递归实现的一个缺陷是它的时间复杂度为O(n log n)。尽管它可以很好地处理我需要处理的所有树形结构,但在Python 3中使用子生成器可能会更好。
[ A, [ B, [C, D] ], [ E, [ F, G ] ] ]
,假设你在访问 E 之前访问了 B,那么你也会在访问 E 之前访问 C 和 D。广度优先搜索意味着在访问任何子节点之前,首先访问同一层级的所有节点,因此在访问 C、D、F 或 G 的任何一个之前,B 和 E 都将被访问。 - Mark Reed在上述给出的使用defaultdict创建单行树的答案的基础上,您可以将其制作成一个类。这将允许您在构造函数中设置默认值,并以其他方式进行构建。
class Tree(defaultdict):
def __call__(self):
return Tree(self)
def __init__(self, parent):
self.parent = parent
self.default_factory = self
这个例子允许你创建一个回溯引用,使得每个节点都可以在树中引用它的父节点。
>>> t = Tree(None)
>>> t[0][1][2] = 3
>>> t
defaultdict(defaultdict(..., {...}), {0: defaultdict(defaultdict(..., {...}), {1: defaultdict(defaultdict(..., {...}), {2: 3})})})
>>> t[0][1].parent
defaultdict(defaultdict(..., {...}), {1: defaultdict(defaultdict(..., {...}), {2: 3})})
>>> t2 = t[0][1]
>>> t2
defaultdict(defaultdict(..., {...}), {2: 3})
>>> t2[2]
3
对于具有有序子节点的树,我通常会做类似于这样的事情(虽然不太通用,但适合我的工作):
class TreeNode(list):
def __init__(self, iterable=(), **attributes):
self.attr = attributes
list.__init__(self, iterable)
def __repr__(self):
return '%s(%s, %r)' % (type(self).__name__, list.__repr__(self),
self.attr)
dict
或DictMixin
或其更现代的后继来完成类似的操作。这是我正在工作的一个项目。
class Tree:
def __init__(self, value, *children):
'''Singly linked tree, children do not know who their parent is.
'''
self.value = value
self.children = tuple(children)
@property
def arguments(self):
return (self.value,) + self.children
def __eq__(self, tree):
return self.arguments == tree.arguments
def __repr__(self):
argumentStr = ', '.join(map(repr, self.arguments))
return '%s(%s)' % (self.__class__.__name__, argumentStr)
使用示例(数字仅作为示例值):t = Tree(1, Tree(2, Tree(4)), Tree(3, Tree(5)))
根据我个人在更高级数据结构方面的经验,我认为你能做的最重要的事情是对树形数据结构的概念有很好的了解。如果你理解这个概念背后的基本机制,就会很容易实现符合你需求的解决方案。有很多描述该概念的优秀资料。在 "计算机程序设计艺术" 的 2.3 章节中,正是这个概念 "拯救" 了我。