将大量字典列表作为磁盘上的查找表
我有一个非常大的字典列表(大小达到几个GB),是从一个API获取的。我想把它用作其他函数的查找表。在Python中有几种对象持久化的方法,你有什么推荐的方式可以把字典列表存储到磁盘上,以便于后续的引用和查找吗?
{
"library_id": "7",
"set_id": "80344779",
"description": "Very long description 1 ...",
"value": "1"
},
{
"library_id": "22",
"set_id": "80344779",
"description": "Very long description 2 ...",
"value": "1"
},
{
"library_id": "24",
"set_id": "80344779",
"description": "Very long description 3 ...",
"value": "8"
},
3 个回答
正如其他回答所提到的,看看现成的数据库模型是很有必要的。如果你想要一个可以随处使用的数据库,可以很简单地用Python创建一个sqlite3数据库。假设你的数据来自一个API,并且只是像你上面列出的那样是一个字典元素的列表,一个最简单的工作示例可能会是:
import sqlite3
# Create a database in memory, in practice you would save to disk
conn = sqlite3.connect(':memory:')
# Read in the data [omitted for brevity]
cmd_create_table='''
CREATE TABLE api_data (
set_id INTEGER,
library_id INTEGER,
description STRING,
value INTEGER);
CREATE INDEX idx_api ON api_data (library_id, set_id);
'''
conn.executescript(cmd_create_table)
cmd_insert = '''INSERT INTO api_data VALUES (?,?,?,?)'''
keys = ["set_id","library_id","description","value"]
for item in data:
val = [item[k] for k in keys]
conn.execute(cmd_insert, val)
def lookup(library_id, set_id):
cmd_find = 'SELECT * FROM api_data WHERE library_id={} AND set_id={}'
cmd = cmd_find.format(library_id, set_id)
return conn.execute(cmd).fetchall()
print lookup(22, 80344779)
>>> [(80344779, 22, u'Very long description 2 ...', 1)]
一种方法是创建一个模型(使用Django模型 https://docs.djangoproject.com/en/dev/topics/db/models/),这个模型的类可以和你字典里的字段对应,然后把每个字典保存成对象,像这样:
大概是这样的:
from django.db import models
class MyDict(models.model):
library_id = models.CharField(max_length=30)
set_id = models.CharField(max_length=30)
description = models.CharField(max_length=30)
如果你的“library_id”是唯一的,可以把它设为主键,这样你就可以通过library_id来查找。
如果你是在Google App Engine上托管的,也可以使用Google App Engine的ndb API来实现同样的功能。 https://developers.google.com/appengine/docs/python/ndb/
你的数据看起来是比较规律的,也就是说字典的键没有变化,对吧?你可以简单地使用像MongoDB这样的文档型数据库,但我觉得用一个简单的基于SQL的数据库可能会更高效,而且实现起来也比较简单。
另外的选择可以是pickle模块(不推荐用于非常大的对象,因为它们会一次性加载到内存中),或者shelve,它是在pickle的基础上构建的,但在处理大文件时更高效(因为它们不会一次性加载到内存中)。shelve的好处在于它的语法和Python的字典语法很相似,使用起来应该很简单(可以查看链接)。而且你不需要设置MongoDB或MySQL数据库(这在Windows上可能会比较复杂)。pickle和shelve都是标准库的一部分。
你也可以看看datasets,它有一个易于使用的界面。它在后台使用的是sqlite数据库。
如果你处理的是非常大的文件(比如超过2GB),我建议不要使用datasets或shelve,而是使用更成熟的解决方案,比如sqlalchemy(加上MySQL数据库)或者MongoDB及其Python接口(PyMongo)。