簡體   English   中英

defaultdict vs dict元素初始化

[英]defaultdict vs dict element initialization

我正在嘗試優化腳本的性能,該腳本在給出的每個單詞的詞典中查找相似的單詞。

每個唯一的單詞將被分成字母n-gram,並且對於每個n-gram,詞典返回包含相同字母n-gram的單詞列表。 然后將此列表中的每個單詞作為鍵添加到字典中,並將其值加1。 這給了我一個具有相應頻率分數的類似單詞的字典。

word_dict = {}
get = word_dict.get
for letter_n_gram in word:
    for entry in lexicon[n_gram]:
        word_dict[entry] = get(entry, 0) + 1

這個實現可以工作,但是通過切換collections.defaultdictdict可以更快地運行腳本。

word_dd = defaultdict(int)
for letter_n_gram in word:
    for entry in lexicon[n_gram]:
        word_dd[entry] += 1

沒有其他代碼被更改。

我的印象是兩個代碼片段(最重要的是分數添加)應該以完全相同的方式工作,即如果密鑰存在,將其值增加1,如果它不存在,則創建密鑰並將值設置為1。

但是,在運行新代碼之后,某些鍵的值為0,我覺得這在邏輯上是不可能的。

我對defaultdict功能的邏輯或知識是否有缺陷? 如果沒有, word_dd任何值如何設置為0?

編輯:我也非常確定腳本中沒有其他部分會扭曲這些結果,因為我使用以下代碼在顯示代碼后立即測試字典:

for item in word_dd.iteritems():
    if item[1] == 0:
        print "Found zero value element"
        break

當您訪問defaultdict的密鑰時,如果它不在那里,它將自動創建。 由於我們將int作為默認工廠函數,因此它會創建密鑰並提供默認值0。

from collections import defaultdict
d = defaultdict(int)
print d["a"]
# 0
print d
# defaultdict(<type 'int'>, {'a': 0})

因此,在訪問密鑰之前,您應確保它存在於defaultdict實例中,如下所示

print "a" in d
# False

對密鑰的任何項訪問都將實現該值:

>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> d['foo']
0

使用包含來測試存在而不是:

>>> 'bar' in d
False
>>> 'foo' in d
True

由於你在計算n-gram,你可能想看看collections.Counter()

from collections import Counter

word_counter = Counter()
for letter_n_gram in word:
    word_counter.update(lexicon[n_gram])

其中Counter.update()將更新lexicon[n_gram]表達式返回的所有條目的計數。

defaultdict(int)Counter()對象自動實現值,默認為整數0

唉,我在代碼中發現了錯誤。

由於在我的輸入集中有許多隨后的單詞n-gram和相同的測試單詞,我只是每個唯一的測試單詞創建一個相似單詞的字典。

然后,該字典用於其他目的,其中密鑰被多次測試。 當然,如果字典是collections.defaultdict並且默認工廠未設置為None ,則可以創建零值元素。

然而,在每個主循環中進行零值元素的測試 - 因此找到在前一循環中創建的零值元素。

在將測試代碼縮進到適當的部分之后,結果如預期的那樣 - 在創建之后不會立即出現零值元素。

我想向所有人道歉,因為我的問題錯誤和不完整 - 其他人都無法找到錯誤。

暫無
暫無

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

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