在内存中有一个需要查询,排序和任意聚合的“表”确实确实需要SQL。您说您尝试过SQLite,但是您是否意识到SQLite可以使用仅内存数据库?
connection = sqlite3.connect(':memory:')
然后,您可以使用SQLite的所有功能在内存中创建/删除/查询/更新表,完成后不留文件。从Python
2.5开始,
sqlite3它在标准库中,因此它并不是真正的“滥杀滥伤” IMO。
这是一个示例如何创建和填充数据库的示例:
import csvimport sqlite3db = sqlite3.connect(':memory:')def init_db(cur): cur.execute('''CREATE TABLE foo ( Row INTEGER, Name TEXT, Year INTEGER, Priority INTEGER)''')def populate_db(cur, csv_fp): rdr = csv.reader(csv_fp) cur.executemany(''' INSERT INTO foo (Row, Name, Year, Priority) VALUES (?,?,?,?)''', rdr)cur = db.cursor()init_db(cur)populate_db(cur, open('my_csv_input_file.csv'))db.commit()
如果您真的不想使用SQL,则可能应该使用字典列表:
lod = [ ] # "list of dicts"def populate_lod(lod, csv_fp): rdr = csv.DictReader(csv_fp, ['Row', 'Name', 'Year', 'Priority']) lod.extend(rdr)def query_lod(lod, filter=None, sort_keys=None): if filter is not None: lod = (r for r in lod if filter(r)) if sort_keys is not None: lod = sorted(lod, key=lambda r:[r[k] for k in sort_keys]) else: lod = list(lod) return loddef lookup_lod(lod, **kw): for row in lod: for k,v in kw.iteritems(): if row[k] != str(v): break else: return row return None
然后测试得出:
>>> lod = []>>> populate_lod(lod, csv_fp)>>> >>> pprint(lookup_lod(lod, Row=1)){'Name': 'Cat', 'Priority': '1', 'Row': '1', 'Year': '1998'}>>> pprint(lookup_lod(lod, Name='Aardvark')){'Name': 'Aardvark', 'Priority': '1', 'Row': '4', 'Year': '2000'}>>> pprint(query_lod(lod, sort_keys=('Priority', 'Year')))[{'Name': 'Cat', 'Priority': '1', 'Row': '1', 'Year': '1998'}, {'Name': 'Dog', 'Priority': '1', 'Row': '3', 'Year': '1999'}, {'Name': 'Aardvark', 'Priority': '1', 'Row': '4', 'Year': '2000'}, {'Name': 'Wallaby', 'Priority': '1', 'Row': '5', 'Year': '2000'}, {'Name': 'Fish', 'Priority': '2', 'Row': '2', 'Year': '1998'}, {'Name': 'Zebra', 'Priority': '3', 'Row': '6', 'Year': '2001'}]>>> pprint(query_lod(lod, sort_keys=('Year', 'Priority')))[{'Name': 'Cat', 'Priority': '1', 'Row': '1', 'Year': '1998'}, {'Name': 'Fish', 'Priority': '2', 'Row': '2', 'Year': '1998'}, {'Name': 'Dog', 'Priority': '1', 'Row': '3', 'Year': '1999'}, {'Name': 'Aardvark', 'Priority': '1', 'Row': '4', 'Year': '2000'}, {'Name': 'Wallaby', 'Priority': '1', 'Row': '5', 'Year': '2000'}, {'Name': 'Zebra', 'Priority': '3', 'Row': '6', 'Year': '2001'}]>>> print len(query_lod(lod, lambda r:1997 <= int(r['Year']) <= 2002))6>>> print len(query_lod(lod, lambda r:int(r['Year'])==1998 and int(r['Priority']) > 2))0
我个人更喜欢SQLite版本,因为它可以更好地保留您的类型(在Python中无需额外的转换代码)并且可以轻松扩展以适应将来的需求。但是话又说回来,我对SQL非常满意,所以对YMMV来说很满意。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)