[英]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.defaultdict
的dict
可以更快地運行腳本。
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.