我正在寻找一个好的Tree数据结构类。我遇到过这个软件包,但是由于我对Python相对较新(不是编程),所以我不知道是否还有更好的软件包。
我想在这里听到来自Pythonista的消息-您是否有喜欢的树脚本经常使用并会推荐使用?
[编辑]
为了澄清,用“树”来表示,是指一个简单的无序树(嗯,这是一个递归定义,但希望可以使情况有所澄清)。关于我需要的树(即用例)。我正在从一个平面文件中读取树数据,并且需要从该数据构建一棵树并遍历树中的所有节点。
我正在寻找一个好的Tree数据结构类。我遇到过这个软件包,但是由于我对Python相对较新(不是编程),所以我不知道是否还有更好的软件包。
我想在这里听到来自Pythonista的消息-您是否有喜欢的树脚本经常使用并会推荐使用?
[编辑]
为了澄清,用“树”来表示,是指一个简单的无序树(嗯,这是一个递归定义,但希望可以使情况有所澄清)。关于我需要的树(即用例)。我正在从一个平面文件中读取树数据,并且需要从该数据构建一棵树并遍历树中的所有节点。
Answers:
自己动手。例如,仅将树建模为列表列表。在人们可以提供更好的建议之前,您应该详细说明自己的特定需求。
为了回答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中的子生成器会有所帮助。
您可以像这样构建一棵漂亮的辞典树:
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(original pyTree):
https://github.com/caesar0301/treelib
可以帮助您...
使用defaultdict在单行Tree上面给出的答案的基础上,可以将其设为类。这将允许您在构造函数中设置默认值,并以其他方式在其上进行构建。
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
接下来,您甚至可以覆盖类Tree上的__setattr__,以便在重新分配父级时,会将其作为子级从该父级中删除。这种模式有很多很棒的东西。
对于有顺序的孩子的树,我通常会做这样的事情(尽管通用性稍差一些,是针对我的工作量身定制的):
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)
如果要通过密钥访问无序的子代,则可以执行与a dict或use DictMixin或它或更现代的后代类似的操作。
pyTree中另一个很好且易于使用的树实现是pyTree:https : //github.com/caesar0301/pyTree
pyTree还提供了可视化树的可能性:
Harry[harry]
|___ Jane[jane]
| |___ Diane[diane]
| |___ George[george]
| |___ Jill[jill]
| |___ Mary[mary]
| |___ Mark[mark]
|___ Bill[bill]
这是我正在做的事情。
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)))