在defaultdict中使用构造函数是否有效

时间:2019-06-22 06:55:08

标签: python python-3.x

我试图查看是否可以在defaultdict中使用构造函数,但我无法运行代码并获得递归错误。只是想知道是否有可能:

from collections import defaultdict

class TrieNode:
    def __init__(self, char):
        self.children = defaultdict(TrieNode(char))
        self.is_word = False

 a = TrieNode('b')

1 个答案:

答案 0 :(得分:2)

在构造函数中使用defaultdict并没有错。问题是您需要向它传递一个函数,当您添加新键时,它会调用 it 。制作字典时,当前正在调用该函数。结果,您将不断地无限拨打TrieNode('b')

您需要使用类似这样的名称来调用它:

self.children = defaultdict(TrieNode)

然后,当您在children中引用未知密钥时,它将为您调用TrieNode()。但是,这意味着您不想在构造函数中使用其他参数。

那可能没问题,因为您通常在特里添加单词,并且需要通过同一节点添加很多单词。一种选择是做类似的事情:

from collections import defaultdict

class TrieNode:
    def __init__(self):
        self.children = defaultdict(TrieNode)
        self.is_word = False
        self.val = ''

    def add(self, word):
        self.val= word[0]
        if (len(word) == 1):
            self.is_word = True
        else:
            self.children[word[0]].add(word[1:])

    def words(self):
        if self.is_word:
            yield self.val
        for letter, node in self.children.items():
            yield from (letter + child for child in node.words())

然后可以在其中添加单词,它将使TrieNodes成为默认词典中的内容:

node = TrieNode()
node.add("dog")
node.add("catnip")
node.add("cats")
node.add("cat")
node.add("crunch")

node.children['c'].children

> defaultdict(__main__.TrieNode,
        {'a': <__main__.TrieNode at 0x179c70048>,
         'r': <__main__.TrieNode at 0x179c70eb8>})

您可以看到您的孩子有一个c键,该键指向一个TrieNode,其孩子是defaultdict,ar指向下一个。

这使您可以使用生成器轻松提取单词:

list(node.words())

> ['dog', 'cat', 'cats', 'catnip', 'crunch']