2014-10-09 131 views
-1

我想動態添加嵌套字典中的值。我試圖用它們的詞性標籤來緩存兩個詞的相似性分數。動態添加嵌套字典

總之,我想存儲這樣的價值; synset_cache[word1][word1_tag][word2][word2_tag] = score

class MyClass(Object): 

    def __init__(self): 
     MyClass.synset_cache={} #dict 

    def set_cache(self,word1, word1_tag, word2, word2_tag, score) 
     try: 
      MyClass.synset_cache[word1] 
     except: 
      MyClass.synset_cache[word1]={} #create new dict 
     try: 
      MyClass.synset_cache[word1][word1_tag] 
     except: 
      MyClass.synset_cache[word1][word1_tag]={} #create new dict 
     try: 
      MyClass.synset_cache[word1][word1_tag][word2] 
     except: 
      MyClass.synset_cache[word1][word1_tag][word2]={} #create new dict 
     #store the value 
     MyClass.synset_cache[word1][word1_tag][word2][word2_tag] = score 

但我得到這個錯誤。

Type error: list indices must be integers, not unicode 

它顯示的行號是MyClass.synset_cache[word1][word1_tag]={} #create new dict

我該如何得到這個工作?

編輯: 根據@羅布的評論他的答案;我用另一種方法爲這個MyClass.synset_cache分配一個列表(注意它在類級別)。所以這個代碼部分沒有錯誤。

+0

誰曾經投票過?我可以知道爲什麼嗎? – 2014-10-09 03:31:37

回答

1

使用dict.setdefault

這可能會實現:

#UNTESTED 
d = MyClass.synset_cache.setdefault(word1, {}) 
d = d.setdefault(word1_tag, {}) 
d = d.setdefault(word2, {}) 
d[word2_tag] = score 

或者,你可以用這個方便的遞歸defaultdict自動跳起字典的一個新的水平。 (見:herehere和)

import collections 
def tree(): 
    return collections.defaultdict(tree) 

class MyClass(Object): 
    def __init__(self): 
     MyClass.synset_cache=tree() 

    def set_cache(self,word1, word1_tag, word2, word2_tag, score) 
     MyClass.synset_cache[word1][word1_tag][word2][word2_tag] = score 
+0

好吧,我會嘗試:) – 2014-10-09 03:04:10

+0

越來越AttributeError:列表對象沒有屬性'setdefault'在'd = d.setdefault(word1_tag,{})''。 – 2014-10-09 03:11:02

+1

然後,除了您向我們展示的內容外,您還有一些代碼正在執行類似於「MyClass.synset_cache [word1] = []'」的操作。請將您的程序縮小到可以演示問題的最小程序,並將整個簡短程序複製粘貼到原始問題中。 – 2014-10-09 03:12:07

0

這將取決於數據,至少對一些測試數據(見下文),代碼不會產生錯誤。你打電話過得怎麼樣?

此外,請注意,如上所述,由於某些語法錯誤(即沒有冒號來結束def set_cache行),它將不會編譯。

下面是一些調整了對編譯代碼的一些例子調用數據,以及如何漂亮的印痕:

#!/usr/bin/env python 

import pprint 

class MyClass(): 

    def __init__(self): 
     MyClass.synset_cache={} #dict 

    def set_cache(self,word1, word1_tag, word2, word2_tag, score): 
     try: 
      MyClass.synset_cache[word1] 
     except: 
      MyClass.synset_cache[word1]={} #create new dict 
     try: 
      MyClass.synset_cache[word1][word1_tag] 
     except: 
      MyClass.synset_cache[word1][word1_tag]={} #create new dict 
     try: 
      MyClass.synset_cache[word1][word1_tag][word2] 
     except: 
      MyClass.synset_cache[word1][word1_tag][word2]={} #create new dict 
     #store the value 
     MyClass.synset_cache[word1][word1_tag][word2][word2_tag] = score 


x = MyClass() 

x.set_cache('foo', 'foo-tag', 'bar', 'bar-tag', 100) 

pp = pprint.PrettyPrinter(indent=4) 

pp.pprint(x.synset_cache) 

,輸出:注意

一對夫婦的其他東西..

我建議使用in樣式語法來檢查關鍵存在,而不是try - except。它更緊湊,更Pythonic。

此外,您的主要變量synset_cache是類級別(即靜態)。你的意思是這樣嗎?

+0

對不起,我粘貼的代碼部分沒有錯誤。正如@Rob指出的,我在錯誤的另一種方法中爲這個相同的變量賦值了一個列表。 – 2014-10-09 03:24:12

+0

我正在使用多個線程,並計算相似性是昂貴的。所以我決定將它緩存在類級別並使用'threading.Lock()'。 – 2014-10-09 03:26:09

+1

啊。不過,我仍然建議切換到'in'風格的鍵盤檢查語法(不是因爲我上面提到的原因,它會產生功能差異)。 – khampson 2014-10-09 03:28:50