我有一本非常大的字典,其中包含大约400万个密钥,这些密钥是我在阅读大文本文件后获得的。我需要我的脚本运行得更快,现在我正在寻找一种正确的方法来做到这一点。我试图在某个地方保存字典以便更快地访问它,但是使用pickle实际上是将我的速度降低到150秒才能读取它!读取文本文件要快得多,这看起来很奇怪。我也尝试使用sqlite将其保存到数据库中,但这也花了太长时间。这种问题通常如何解决?
答案 0 :(得分:0)
如果您使用python2,我建议使用wiredtiger作为快速键/值存储。我建议使用wiredtiger develop分支。如果您的系统上安装了swig3和python2-dev,则可以执行以下操作来安装wiredtiger:
git clone https://github.com/wiredtiger/wiredtiger --branch=develop
cd wiredtiger
./autogen.sh && ./configure --enable-python && make && make install
这是一个小型数据库类,允许使用字符串值获取和设置字符串键:
from wiredtiger import wiredtiger_open
WT_NOT_FOUND = -31803
class KV(object):
def __init__(self, path):
# init wiredtiger
self._wiredtiger = wiredtiger_open(path, 'create')
self.session = self._wiredtiger.open_session()
# create key/value table
self.session.create('table:kv', 'key_format=S,value_format=S')
self.kv = self.session.open_cursor('table:kv')
def close(self):
self._wiredtiger.close()
def __setitem__(self, key, value):
self.kv.set_key(key)
self.kv.set_value(value)
self.kv.insert()
def __getitem__(self, key):
self.kv.set_key(key)
if self.kv.search() == WT_NOT_FOUND:
msg = "key '%s' not found" % key
raise KeyError(msg)
else:
return self.kv.get_value()
kv = KV('./data')
kv['foo'] = 'bar'
assert kv['foo'] == 'bar'
如果使用wiretiger令人生畏,可以使用plyvel bindings尝试leveldb。 API非常简单,但速度要慢得多。
使用plyvel,您可以执行以下操作:
import plyvel
db = plyvel.DB('/tmp/testdb/', create_if_missing=True)
db.put('key', 'value')
# later
assert db.get('key') == 'value'
否则,如果你使用python2,那就是builtin shelve module。