我有4亿行独特的键值信息,我希望能够在脚本中快速查找。我想知道这样做的方式是什么。我确实考虑了以下但不确定是否有一种磁盘映射字典的方法,并且除了在字典创建期间没有使用大量内存。
如果有任何不清楚的地方,请告诉我。
谢谢! -Abhi
答案 0 :(得分:17)
如果你想坚持一本大字典,你基本上是在看一个数据库。
Python内置了对sqlite3的支持,它为您提供了一个由磁盘上的文件支持的简单数据库解决方案。
答案 1 :(得分:12)
原则上shelve模块完全符合您的要求。它提供了由数据库文件支持的持久字典。键必须是字符串,但搁置将处理酸洗/去除值。 db文件的类型可以有所不同,但它可以是Berkeley DB哈希,这是一个非常轻量级的键值数据库。
您的数据大小听起来很大,因此您必须进行一些测试,但搁置/ BDB可能取决于它。
注意:bsddb模块已被弃用。可能搁置将来不会支持BDB哈希。
答案 2 :(得分:10)
没有人提到过dbm。它像文件一样打开,表现得像字典,属于标准发行版。
来自文档http://docs.python.org/release/3.0.1/library/dbm.html
import dbm
# Open database, creating it if necessary.
db = dbm.open('cache', 'c')
# 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'
# Loop through contents. Other dictionary methods
# such as .keys(), .values() also work.
for k, v in db.iteritems():
print(k, '\t', v)
# Storing a non-string key or value will raise an exception (most
# likely a TypeError).
db['www.yahoo.com'] = 4
# Close when done.
db.close()
我会在任何更奇特的形式之前尝试这个,并且使用shelve / pickle会在加载时将所有东西都拉到内存中。
干杯
添
答案 3 :(得分:5)
毫无疑问(在我看来),如果你想要坚持下去,那么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。
答案 4 :(得分:4)
我认为你不应该尝试腌制的字典。我很确定Python会在每次都沾染整个东西,这意味着你的程序会等待I / O超过可能的时间。
这就是发明数据库的问题。您正在考虑“NoSQL”,但SQL数据库也可以工作。你应该能够使用SQLite;我从未创建过大的SQLite数据库,但根据SQLite限制的讨论,4亿条目应该没问题。
What are the performance characteristics of sqlite with very large database files?
答案 5 :(得分:2)
我个人使用LMDB及其python binding获取数百万条记录数据库。 即使对于大于RAM的数据库,它也非常快。 它嵌入在流程中,因此不需要服务器。 使用pip来管理依赖性。
唯一的缺点是你必须指定数据库的最大大小。 LMDB将mmap这个大小的文件。如果太小,插入新数据将引发错误。要大,请创建稀疏文件。