将单词列表解析为树

时间:2012-06-04 09:26:41

标签: python parsing data-structures tree

我有一个单词列表。例如:

reel
road
root
curd

我想以反映以下结构的方式存储这些数据:

Start -> r -> e -> reel
           -> o -> a -> road
                   o -> root
         c -> curd

我很清楚我需要实现一棵树。从这棵树,我必须能够轻松获得统计信息,如节点的高度,节点的后代数,搜索节点等。 添加节点应“自动”将其添加到树中的正确位置,因为此位置是唯一的。

它还希望能够以实际图形树的形式可视化数据。由于树将巨大,我需要在可视化上进行缩放/平移控制。当然,漂亮的可视化总是比丑陋的更好。

有没有人知道Python包可以让我简单地实现这一切?自己编写代码需要很长时间。您认为http://packages.python.org/ete2/适合此任务吗?

我在Python 2.x上,顺便说一下。


我发现NLTK有一个特里类 - nltk.containers.trie。这对我来说很方便,因为我已经使用了NLTK。有谁知道如何使用这个类?我在任何地方都找不到任何例子!例如,如何在trie中添加单词?

2 个答案:

答案 0 :(得分:3)

ETE2是一个树木探索的环境,原则上用于浏览,构建和探索系统发育树,我很久以前就已将它用于这些目的。 但是,如果你正确设置数据,你可能会完成它。

您只需将paretheses放在任何需要分割树木并创建分支的地方。请参阅以下示例,该示例取自ETE doc。 如果你改变这些“(A,B,(C,D));”对于你的单词/字母,应该这样做。

from ete2 import Tree
unrooted_tree = Tree( "(A,B,(C,D));" )
print unrooted_tree

输出:

     /-A
    |
----|--B
    |
    |     /-C
     \---|
          \-D

...此软件包将让您完成所需的大部分操作,让您有机会单独选择每个分支,并以简单的方式操作它。 无论如何,我建议你看一下教程,不是很难:)

答案 1 :(得分:3)

我认为以下示例使用ETE工具包完成了您想要的功能。

from ete2 import Tree

words = [ "reel", "road", "root", "curd", "curl", "whatever","whenever", "wherever"]

#Creates a empty tree
tree = Tree()
tree.name = ""
# Lets keep tree structure indexed
name2node = {}
# Make sure there are no duplicates
words = set(words)
# Populate tree
for wd in words:
    # If no similar words exist, add it to the base of tree
    target = tree

    # Find relatives in the tree
    for pos in xrange(len(wd), -1, -1):
        root = wd[:pos]
        if root in name2node:
            target = name2node[root]
            break

    # Add new nodes as necessary
    fullname = root 
    for letter in wd[pos:]:
        fullname += letter 
        new_node = target.add_child(name=letter, dist=1.0)
        name2node[fullname] = new_node

        target = new_node

# Print structure
print tree.get_ascii()
# You can also use all the visualization machinery from ETE
# (http://packages.python.org/ete2/tutorial/tutorial_drawing.html)
# tree.show()

# You can find, isolate and operate with a specific node using the index
wh_node = name2node["whe"]
print wh_node.get_ascii()

# You can rebuild words under a given node
def recontruct_fullname(node):
    name = []
    while node.up:
        name.append(node.name)
        node = node.up
    name = ''.join(reversed(name))
    return name

for leaf in wh_node.iter_leaves():
    print recontruct_fullname(leaf)


                    /n-- /e-- /v-- /e-- /-r
               /e--|
     /w-- /h--|     \r-- /e-- /v-- /e-- /-r
    |         |
    |          \a-- /t-- /e-- /v-- /e-- /-r
    |
    |     /e-- /e-- /-l
----|-r--|
    |    |     /o-- /-t
    |     \o--|
    |          \a-- /-d
    |
    |               /-d
     \c-- /u-- /r--|
                    \-l