我有 4 亿行唯一的键值信息,我希望可以在脚本中快速查找这些信息。我想知道什么是一个巧妙的方法来做到这一点。我确实考虑了以下内容,但不确定是否有一种方法可以磁盘映射字典并且除了在字典创建期间之外不使用大量内存。
如果有任何不清楚的地方请告诉我。
谢谢! -阿比
如果你想持久化一个大字典,你基本上就是在查看数据库。
Python 内置了对 sqlite3 的支持,它为您提供了一个由磁盘上的文件支持的简单数据库解决方案。
没有人提到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.
我会在任何更奇特的形式之前尝试这个,并且使用 shelve/pickle 会在加载时将所有内容拉入内存。
干杯
蒂姆
原则上,shelve模块完全可以满足您的需求。它提供由数据库文件支持的持久字典。键必须是字符串,但搁置将处理酸洗/取消酸洗值。数据库文件的类型可以有所不同,但它可以是 Berkeley DB 哈希,这是一个出色的轻量级键值数据库。
您的数据量听起来很大,因此您必须进行一些测试,但 shelve/BDB 可能足以胜任。
注意:bsddb模块已被弃用。未来可能搁置将不支持 BDB 哈希。
毫无疑问(在我看来),如果你希望这种情况持续下去,那么 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 亿个条目应该没问题。