Python 搁置模块的大小问题

Size issues with Python shelve module

我想使用搁置模块存储一些词典,但是,我 运行遇到了大小问题。我使用 Python 3.5.2 和最新的搁置模块。

我有一个单词列表,我想创建一个从双字母组(字符级别)到单词的映射。该结构将如下所示:

'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 数据库大约为 120gb,它仍然没有读取 1.3M 字的一半从文件中列出。我在这里做错了什么?

这里的问题与其说是键的数量,不如说是每个键都引用了一个单词列表。

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

然而,在 shelve 中,每个值都被 pickle 并单独存储,这意味着必须存储列表中单词的 具体副本 对于每个值。由于您的设置最终会将给定单词添加到大量列表中,因此这会大大增加您的数据需求。

我会在这里改用 SQL 数据库。 Python 与 sqlite3 捆绑在一起。如果您为单个单词创建一个 table,为每个可能的二元组创建第二个 table,第三个简单地链接两者(多对多映射,将二元组行 ID 链接到单词行id),这可以非常有效地完成。然后您可以进行非常有效的查找,因为 SQLite 非常擅长为您管理内存和索引。