【问题标题】:Parsing a list of words into a tree将单词列表解析成树
【发布时间】:2012-06-04 09:26:41
【问题描述】:

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

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

【问题讨论】:

  • 听起来你在寻找一个trie
  • @EliBendersky:你是对的——看来我是。你知道 Python 包可以轻松创建、操作和可视化尝试吗?
  • graphviz 绑定,或类似 NetworkX 或其他图形处理库

标签: python parsing data-structures tree


【解决方案1】:

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

您只需在需要拆分树并创建分支的任何地方放置括号。请参阅以下示例,取自 ETE 文档。 如果您更改这些“(A,B,(C,D));”对于您的单词/字母,应该完成。

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

输出:

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

...这个包可以让你做大部分你想要的操作,让你有机会单独选择每个分支,并以一种简单的方式进行操作。 无论如何,我建议你看一下教程,并不难:)

【讨论】:

  • 问题是,我无法像您说明的那样在构造函数中创建整个 trie。它需要一次创建一个单词,并将每个单词插入正确的位置。 ETE2 可以自动为我执行此操作吗?
  • @VelvetGhost,我对尝试不太了解,但是......有可能单独手动创建每棵树,然后按首选顺序连接它们,告诉 ETE在哪里连接树木?而这一点,我确信 ETE2 可以做到……
  • 有可能,但我相信有更简单的方法。我找到了一个 trie 实现(见下文),但不知道如何使用它!
【解决方案2】:

我认为以下示例使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 2011-05-08
    • 1970-01-01
    相关资源
    最近更新 更多