我有 4 亿行唯一的键值信息,我希望可以在脚本中快速查找这些信息。我想知道这样做的巧妙方法是什么。我确实考虑了以下内容,但不确定是否有一种方法可以对字典进行磁盘映射,并且除了在创建字典期间之外不使用大量内存。
- 腌制字典对象:不确定这是否是我的问题的最佳解决方案
- NoSQL 类型 dbases :理想情况下,希望对第三方的依赖最小的东西加上键值就是简单的数字。如果你觉得这仍然是最好的选择,我也想听听。也许它会说服我。
如果有任何不清楚的地方,请告诉我。
谢谢!-阿比
我有 4 亿行唯一的键值信息,我希望可以在脚本中快速查找这些信息。我想知道这样做的巧妙方法是什么。我确实考虑了以下内容,但不确定是否有一种方法可以对字典进行磁盘映射,并且除了在创建字典期间之外不使用大量内存。
如果有任何不清楚的地方,请告诉我。
谢谢!-阿比
如果你想持久化一个大字典,你基本上是在查看一个数据库。
Python 内置了对sqlite3的支持,它为您提供了一个由磁盘上的文件支持的简单数据库解决方案。
原则上,搁置模块完全符合您的要求。它提供了一个由数据库文件支持的持久字典。键必须是字符串,但 shelve 会处理酸洗/取消酸洗值。db 文件的类型可以变化,但可以是Berkeley DB哈希,这是一个优秀的轻量级键值数据库。
您的数据量听起来很大,因此您必须进行一些测试,但搁置/BDB 可能取决于它。
注意:bsddb模块已被弃用。将来可能搁置不支持 BDB 哈希。
没有人提到dbm。它像文件一样打开,行为像字典,并且在标准发行版中。
来自文档https://docs.python.org/3/library/dbm.html
import dbm
# Open database, creating it if necessary.
with dbm.open('cache', 'c') as db:
# Record some values
db[b'hello'] = b'there'
db['www.python.org'] = 'Python Website'
db['www.cnn.com'] = 'Cable News Network'
# Note that the keys are considered bytes now.
assert db[b'www.python.org'] == b'Python Website'
# Notice how the value is now in bytes.
assert db['www.cnn.com'] == b'Cable News Network'
# Often-used methods of the dict interface work too.
print(db.get('python.org', b'not present'))
# Storing a non-string key or value will raise an exception (most
# likely a TypeError).
db['www.yahoo.com'] = 4
# db is automatically closed when leaving the with statement.
我会在任何更奇特的形式之前尝试这个,并且使用搁置/泡菜会在加载时将所有内容拉入内存。
干杯
蒂姆
毫无疑问(在我看来),如果您希望这种情况持续存在,那么 Redis 是一个不错的选择。
import redis
ds = redis.Redis(host="localhost", port=6379)
with open("your_text_file.txt") as fh:
for line in fh:
line = line.strip()
k, _, v = line.partition("=")
ds.set(k, v)
上面假设文件的值如下:
key1=value1
key2=value2
etc=etc
根据您的需要修改插入脚本。
import redis
ds = redis.Redis(host="localhost", port=6379)
# Do your code that needs to do look ups of keys:
for mykey in special_key_list:
val = ds.get(mykey)
为什么我喜欢 Redis。
我认为你不应该尝试腌制的字典。我很确定 Python 每次都会吃掉整个东西,这意味着你的程序等待 I/O 的时间可能比必要的要长。
这就是发明数据库的问题。您正在考虑“NoSQL”,但 SQL 数据库也可以工作。您应该能够为此使用 SQLite;我从来没有做过这么大的 SQLite 数据库,但是根据这个关于 SQLite 限制的讨论,4 亿个条目应该没问题。