2016-09-19 78 views
0

我想使用搁置模块来存储几个字典,但是,我遇到了大小问题。我使用Python 3.5.2和最新的搁置模块。Python搁置模块的大小问题

我有一个单词列表,我想创建一个从bigrams(角色级别)到单词的地图。结构看起来像这样:

'aa': 'aardvark', 'and', ... 
'ab': 'absolute', 'dab', ... 
... 

我读了一个由大约130万字组成的大文件。所以字典变得很大。这是代码:

self.bicharacters // part of class 
def _create_bicharacters(self): 
    ''' 
    Creates a bicharacter index for calculating Jaccard coefficient. 
    ''' 
    with open('wordlist.txt', encoding='ISO-8859-1') as f: 
     for line in f: 

      word = line.split('\t')[2] 

      for i in range(len(word) - 1): 
       bicharacter = (word[i] + word[i+1]) 

       if bicharacter in self.bicharacters: 
        get = self.bicharacters[bicharacter] 
        get.append(word) 
        self.bicharacters[bicharacter] = get 
       else: 
        self.bicharacters[bicharacter] = [word] 

当我跑了使用普通的Python字典这段代码,我没有碰到的问题,但我不能放过这些类型的内存资源由于程序的其余部分也有相当大的内存占用。

所以我尝试使用搁置模块。但是,当我使用shelve运行上面的代码时,由于磁盘上没有更多内存,程序会在一段时间后停止,所创建的shelve db大约为120GB,并且它仍然没有读取文件中的1.3M字列表的一半。我在这里做错了什么?

+0

为什么你用'pip'安装'shelve'?它是标准库的一部分,它基本上是['pickle'](https://docs.python.org/3/library/pickle.html)和['dbm'](https:// docs .python.org/3 /库/ dbm.html)。同名的[PyPI包](https://pypi.python.org/pypi/shelve)是完全不同的东西。 –

+0

您可能想重新使用此工具来使用数据库; ['dbm'格式](https://en.wikipedia.org/wiki/Dbm)并未针对此类大型数据集进行完全优化。 –

+0

@MartijnPieters对不起,没有通过点安装,与其他东西混合。 –

回答

2

这里的问题并不是密钥的数量,而是每个密钥引用一个单词列表。

虽然在内存中作为一个(巨大的)字典,但这并不是一个大问题,因为这些单词只是在列表之间共享;每个列表仅仅是对其他对象的引用顺序,这些对象中的许多对象是相同的,因为每个单词只需要引用一个字符串。

shelve,但是,每个值进行酸洗和单独地存储,这意味着在一个列表中的词的混凝土拷贝将不得不被存储为每个值。由于您的设置最终将给定的单词添加到大量列表中,因此这会使您的数据需求剧增。

我会切换到在这里使用SQL数据库。 Python随附了sqlite3。如果你为单个单词创建一个表格,为每个可能的双字节创建第二个表格,并且第三个表格简单地链接在两者之间(多对多映射,将bigram行标识链接到单词行id),这可以做得很好有效率的。然后,您可以进行高效查找,因为SQLite非常善于为您管理内存和索引。