寻找一个好的Python Tree数据结构

时间:2010-06-09 21:05:23

标签: python

我正在寻找一个好的Tree数据结构类。我遇到了this package,但由于我相对较新的Python(不是编程),我不知道那里是否有更好的。

我想在这里听到Pythonistas的消息 - 您是否有一个经常使用并且会推荐的最喜欢的树脚本?

[编辑]

澄清一下,'Tree',我的意思是一个简单的无序树(嗯,这有点像递归定义 - 但希望这有点澄清一些事情)。关于我需要树(即用例)。我正在从平面文件中读取树数据,我需要从数据构建一个树并遍历树中的所有节点。

10 个答案:

答案 0 :(得分:71)

你可以像这样构建一个很好的dicts dicts:

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'})}) 

有关详细信息,请查看the gist

答案 1 :(得分:39)

我找到了一个由Brett Alistair Kromkamp编写的模块,该模块尚未完成。我完成了它并在github上公开并将其重命名为treelib(原始pyTree):

https://github.com/caesar0301/treelib

可以帮助你......

答案 2 :(得分:37)

滚动你自己。例如,只需将树建模为列表列表。在人们提供更好的推荐之前,您应该详细说明您的具体需求。

在回答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中的子生成器会有所帮助。

答案 3 :(得分:8)

the answer given above with the single line Tree using 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

接下来,您甚至可以覆盖类Tree上的__setattr__,这样在重新分配父级时,它会将其作为子级从父级中删除。这种模式有很多很酷的东西。

答案 4 :(得分:7)

对于有序儿童的树,我通常会做一些这样的事情(尽管不那么通用,适合我正在做的事情):

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或更现代的后代相似的东西。

答案 5 :(得分:6)

使用networkx库基于非循环有向图编写自己的树包装器可能是值得的。

答案 6 :(得分:5)

Python中另一个易于使用的树实现是pyTree: https://github.com/caesar0301/pyTree

pyTree还提供了可视化树的可能性:

Harry[harry]
|___ Jane[jane]
|    |___ Diane[diane]
|         |___ George[george]
|              |___ Jill[jill]
|         |___ Mary[mary]
|    |___ Mark[mark]
|___ Bill[bill]

答案 7 :(得分:4)

这是我正在做的事情。

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)))

答案 8 :(得分:3)

BTrees会有帮助吗?它们是Zope对象数据库代码的一部分。下载整个ZODB软件包有点过分,但我希望BTrees模块至少可以分离。

答案 9 :(得分:1)

我认为,根据我自己在更高级数据结构问题上的经验,你可以在这里做的最重要的事情就是要充分了解tress作为数据结构的一般概念。如果您了解该概念背后的基本机制,那么实现适合您的问题的解决方案将非常容易。有很多很好的资源来描述这个概念。几年前在这个特殊问题上“救了我”的是“计算机程序设计的艺术”第2.3节。