用于大型数据集的Python defaultdict

Lez*_*zan 9 python numpy large-data defaultdict

defaultdict用来存储数百万个短语,所以我的数据结构看起来像mydict['string'] = set(['other', 'strings']).它似乎适用于较小的套装但是当我击中任何超过1000万个按键时,我的程序只是崩溃了有用的信息Process killed.我知道defaultdict内存很重,但是有一个使用defaultdicts 存储的优化方法还是我必须查看其他数据结构,如numpy数组?

谢谢

lmj*_*ns3 5

如果您打算使用单个 Python 进程留在内存中,那么您将不得不放弃dict数据类型——正如您所指出的,它具有出色的运行时性能特征,但它使用了大量内存来帮助您实现.

真的,我认为@msw 的评论和@Udi 的回答是正确的——要扩展,您应该查看磁盘或至少某种类型的进程外存储,可能 RDBMS 是最容易上手的事情。

但是,如果您确定需要保留在内存和进程中,我建议您使用排序列表来存储数据集。您可以在 O(log n) 时间内进行查找,并在恒定时间内进行插入和删除操作,并且您可以自己包装代码,这样用法看起来很像defaultdict. 像这样的事情可能会有所帮助(没有在底部的测试之外进行调试):

import bisect

class mystore:
    def __init__(self, constructor):
        self.store = []
        self.constructor = constructor
        self.empty = constructor()

    def __getitem__(self, key):
        i, k = self.lookup(key)
        if k == key:
            return v
        # key not present, create a new item for this key.
        value = self.constructor()
        self.store.insert(i, (key, value))
        return value

    def __setitem__(self, key, value):
        i, k = self.lookup(key)
        if k == key:
            self.store[i] = (key, value)
        else:
            self.store.insert(i, (key, value))

    def lookup(self, key):
        i = bisect.bisect(self.store, (key, self.empty))
        if 0 <= i < len(self.store):
            return i, self.store[i][0]
        return i, None

if __name__ == '__main__':
    s = mystore(set)
    s['a'] = set(['1'])
    print(s.store)
    s['b']
    print(s.store)
    s['a'] = set(['2'])
    print(s.store)
Run Code Online (Sandbox Code Playgroud)