在Python中将大型哈希表存储到文件中
你好。我有一个函数想要进行缓存,但它可能的值实在太多了。有没有什么简单的方法可以把这些值存储在一个文本文件里,然后从文件中读取呢?比如说,像把计算好的所有小于10^9的质数存到一个文本文件里?我知道从文本文件读取数据会比较慢,但如果数据量真的很大,那也没有其他办法了。谢谢!
7 个回答
你也可以选择一种最简单粗暴的方法,创建一个Python文件,里面只写一条语句:
seedprimes = [3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,
79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173, ...
然后直接导入这个文件就可以了。(这里有一个包含到1万的质数的文件:http://python.pastebin.com/f177ec30。)
from primes_up_to_1e9 import seedprimes
你可以使用 shelve模块 来把一个像字典的结构存储到文件里。下面是来自Python文档的说明:
import shelve
d = shelve.open(filename) # open -- file may get suffix added by low-level
# library
d[key] = data # store data at key (overwrites old data if
# using an existing key)
data = d[key] # retrieve a COPY of data at key (raise KeyError
# if no such key)
del d[key] # delete data stored at key (raises KeyError
# if no such key)
flag = key in d # true if the key exists
klist = list(d.keys()) # a list of all existing keys (slow!)
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2] # this works as expected, but...
d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
# having opened d without writeback=True, you need to code carefully:
temp = d['xx'] # extracts the copy
temp.append(5) # mutates the copy
d['xx'] = temp # stores the copy right back, to persist it
# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.
d.close() # close it
对于一个包含最多到 10**9
的质数的列表,为什么需要用哈希呢?那里的键是什么呢?听起来这正是用一个简单直接的二进制文件的好机会!根据 质数定理,大约有 10**9/ln(10**9)
个这样的质数,也就是大约五千万个,或者稍微少一点。每个质数占用4个字节,那总共也就200MB左右——这正好适合用 array.array("L")
以及它的一些方法,比如 fromfile
等等(具体可以参考 文档)。在很多情况下,你实际上可以把这200MB的数据全部加载到内存中,但在最坏的情况下,你也可以只取其中的一部分(比如通过 mmap 和 array.array
的 fromstring
方法),然后在里面进行二分查找(比如通过 bisect),等等等等。
当你真的需要一个巨大的键值存储时——不是那200MB的小东西,而是几个GB的存储!我以前推荐过 shelve
,但在经历了一些不愉快的实际使用后(比如性能、可靠性等问题),我现在更推荐使用数据库引擎——sqlite就很好,而且自带在Python里,PostgreSQL更棒,像CouchDB这样的非关系型数据库可能更好,等等。