2014-10-09 7 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입니다.

어떻게하면됩니까?

편집 : 그의 답변에 대한 @ Robᵩ의 의견에 따르면; 이 MyClass.synset_cache에 다른 방법으로 목록을 지정했습니다 (클래스 수준에 있음). 따라서이 코드 부분에는 오류가 없습니다.

+0

누구도 투표하지 않았습니까? 왜 그럴 수 있니? –

답변

1

dict.setdefault을 사용하십시오.

이 작동 할 수 있습니다 :

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

또는 자동 DICT의 새로운 수준을 온천이 편리한 재귀 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

좋아요. 시도해 보겠습니다. –

+0

AttributeError를 얻는 중입니다 : list 객체는'd = d.setdefault (word1_tag, {})'에'setdefault' 속성이 없습니다. –

+1

그러면 우리에게 보여준 것 이외의 코드가 있는데, 이는 MyClass.synset_cache [word1] = []'과 같은 일을합니다. 문제를 나타내는 가장 작은 프로그램으로 프로그램을 축소하고 짧은 프로그램 전체를 원래 질문에 복사하여 붙여 넣으십시오. –

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) 

출력 : 아래

는 일부 불통 - 투 - 컴파일 데이터를 호출하는 몇 가지 예제와 코드와 어떻게 꽤 - 인쇄입니다 노트의

{ 'foo': { 'foo-tag': { 'bar': { 'bar-tag': 100}}}} 

몇 가지 다른 일을 ..

try - except이 아닌 키 존재 여부를 확인하려면 in 스타일 구문을 사용하는 것이 좋습니다. 더 작고 Pythonic입니다.

또한 주 변수 인 synset_cache은 클래스 수준 (예 : 정적)입니다. 그게 사실인가요?

+0

죄송합니다. 여기에 붙여 넣은 코드 부분에는 오류가 없습니다. @ Rob가 지적했듯이 나는 잘못된 방법으로이 같은 var에 대한 목록을 다른 방법으로 할당하고있었습니다. –

+0

다중 스레드를 사용하고 유사성을 계산하는 데 많은 비용이 듭니다. 그래서 클래스 수준에서 캐시하고'threading.Lock()'을 사용하기로 결정했습니다. –

+1

아. 나는 여전히'in' 스타일의 키 확인 문법으로 바꾸는 것을 권장 할 것이다. (위에서 언급 한 이유들로 인해 기능상의 차이는 없다.) – khampson

관련 문제