簡體   English   中英

Python `collections.defaultdict` 用於相同的 class

[英]Python `collections.defaultdict` for the same class

我嘗試使用 Trie 數據結構來解決一些編碼問題。 對於 trie 中的每個節點,您通常會放置一個其子節點的引用列表。 因此,如果查找中不存在某些子節點,我考慮使用 defaultdict 創建一個默認的空 trie 節點。 但是,我不知道如何使用 defaultdict 來引用包含它的 class 。

我嘗試了兩種方法,都失敗了。 以下是我嘗試過的。

from dataclasses import dataclass
from collections import defaultdict

@dataclass   
class TrieNode():
    is_word = False
    children = defaultdict("TrieNode")

上面的代碼產生

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 4, in TrieNode
TypeError: first argument must be callable or None
@dataclass   
class TrieNode():
    is_word = False
    children = defaultdict(TrieNode)

以上會產生

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 4, in TrieNode
NameError: name 'TrieNode' is not defined

我的問題是關於如何使用defaultdict優雅地實現這一點。 非常感謝您提前。

您使用children = defaultdict(TrieNode)的第二種方法更接近正確,因為defaultdict需要TrieNode的構造函數才能用TrieNode填充它 - 另一種方法傳遞一個預期可調用的字符串。 您的問題是由於您在 class 完成創建之前訪問名稱TrieNode引起的,並給出NameError 要解決此問題,您可以使用children = defaultdict(lambda: TrieNode()) 這樣,只有在調用 lambda function 時才會查找名稱TrieNode

但是,對於 trie,您希望每個節點都有自己的子字典,並且使用這種方法,修改一個節點的子字典將為所有節點修改它,因為它們的所有字典都是相同的 object。 我建議您使用dataclass.field為每個TrieNode創建一個新字典,如下所示:

from dataclasses import dataclass, field
from collections import defaultdict

@dataclass   
class TrieNode():
    is_word = False
    children : 'TrieNode' = field(default_factory=lambda: defaultdict(TrieNode))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM