【问题标题】:Benefits to Recursive Data Structures in Python?Python中递归数据结构的好处?
【发布时间】:2020-08-12 04:47:52
【问题描述】:

我正在尝试将一些数据结构实现为 Python 中的类(链表、二叉树、尝试等)。对于其中一些结构,我可以尝试将它们实现为dicts-of-dicts(例如,trie 为其子级嵌套层),或者我可以将它们实现为具有包含另一个实例的“下一个”变量对象。

我想知道递归数据结构与将所有子数据存储在成员变量中的优缺点是什么。有速度或内存优势吗?更好的缓存?可读性?

下面是一些示例代码,说明了我在说什么,但我更感兴趣的是理论上的好处,而不是对我的伪代码的批评:)

class Trie:
    def __init__(self) -> None:
        self._trie = {}

    def insert(self, text: str) -> None:
        trie = self._trie
        for char in text:
            if char not in trie:
                trie[char] = {}
            trie = trie[char]
        trie["END"] = True

    def search(self, prefix: str) -> bool:
        trie = self._trie
        for char in prefix:
            if char not in trie:
                return False
            trie = trie[char]
        return True
class RecursiveTrie:
    def __init__(self) -> None:
        self.children: List[Optional[RecursiveTrie]] = [None] * 26
        self.end_of_word = False

    def insert(self, key: str) -> None:
        """
        If not present, inserts key into trie.
        If the key is prefix of trie node, just marks leaf node.
        """
        if not key:
            self.end_of_word = True
            return

        index = self.char_to_index(key[0])
        if self.children[index] is None:
            self.children[index] = RecursiveTrie()

        child = self.children[index]
        child.insert(key[1:])

    def search(self, key: str) -> bool:
        """ Search key in the trie. Returns true if key is present in trie. """
        if not key:
            return True

        index = self.char_to_index(key[0])
        if self.children[index] is None:
            return False

        return self.children[index].search(key[1:])

【问题讨论】:

    标签: python data-structures trie recursive-datastructures


    【解决方案1】:

    IMO 这两种方法中的哪一种真正取决于您要编写的代码是真正的生产代码还是练习。

    对于生产代码,您应该使用第一个版本,它更小且更易于阅读。它将dict 视为基本砖块(就像在 Python 中一样),并且嵌套的 dicts 根本没有问题(考虑到即使 python 中的每个对象属性都在 dict... 使用指向另一个实例的成员而不是乍一看,使用 dict 似乎不是一个好主意)。

    为了理解尝试,第二个版本不依赖于字典(明确地),它是你用 C 甚至 C++ 编写它的方式,与std::map 相比,数组可能有意义(应该通过 profiling 来证明真实数据和真实生产硬件,如今的 CPU 过于复杂,无法预测复杂算法的性能)。 如果您将来需要用低级语言实现 trie 或 trie 的变体,这些知识将很有用。

    生产 python 软件的第二个版本只是让同事和/或你自己未来的生活更加艰难。

    【讨论】:

    • 问题不是搜索单词,而是搜索任何单词的前缀(例如,相同的原因尝试很有用) - 我没有发布 prefix_search() 代码。否则你的解释很有意义,谢谢!
    • @zephyrnx:你完全正确,我没有注意到你在搜索时没有检查END。删除了该评论。
    猜你喜欢
    • 2011-08-08
    • 1970-01-01
    • 2021-04-17
    • 2018-08-27
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多