动态添加嵌套字典

动态添加嵌套字典

问题描述:

我想动态添加嵌套字典中的值。我试图用它们的词性标签来缓存两个词的相似性分数。动态添加嵌套字典

总之,我想存储这样的价值; 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

使用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

这将取决于数据,至少对一些测试数据(见下文),代码不会产生错误。你打电话过得怎么样?

此外,请注意,如上所述,由于某些语法错误(即没有冒号来结束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