ako*_*ian 13 python lookup-tables
假设我没有超过一两个具有不同属性的对象,例如:
UID,名称,值,颜色,类型,位置
我希望能够使用Location ="Boston"或Type ="Primary"调用所有对象.经典的数据库查询类型.
大多数表解决方案(pytables,*sql)对于这么小的数据集来说真的太过分了.我应该简单地迭代所有对象并为每个数据列创建一个单独的字典(在添加新对象时向字典添加值)?
这将创建像这样的dicts:
{'Boston':[234,654,234],'Chicago':[324,765,342]} - 这些3位数的条目代表UID之类的东西.
如你所见,查询这将是一个痛苦.
对替代方案的任何想法?
Ste*_*lla 14
对于小关系问题,我喜欢使用Python的内置集.
对于location ='Boston'OR type ='Primary'的示例,如果您有此数据:
users = {
1: dict(Name="Mr. Foo", Location="Boston", Type="Secondary"),
2: dict(Name="Mr. Bar", Location="New York", Type="Primary"),
3: dict(Name="Mr. Quux", Location="Chicago", Type="Secondary"),
#...
}
Run Code Online (Sandbox Code Playgroud)
您可以WHERE ... OR ...像这样执行查询:
set1 = set(u for u in users if users[u]['Location'] == 'Boston')
set2 = set(u for u in users if users[u]['Type'] == 'Primary')
result = set1.union(set2)
Run Code Online (Sandbox Code Playgroud)
或者只有一个表达式:
result = set(u for u in users if users[u]['Location'] == 'Boston'
or users[u]['Type'] == 'Primary')
Run Code Online (Sandbox Code Playgroud)
您还可以使用itertools中的函数来创建相当有效的数据查询.例如,如果你想做类似于GROUP BY city:
cities = ('Boston', 'New York', 'Chicago')
cities_users = dict(map(lambda city: (city, ifilter(lambda u: users[u]['Location'] == city, users)), cities))
Run Code Online (Sandbox Code Playgroud)
您还可以手动构建索引(构建dict映射位置到用户ID)以加快速度.如果这变得太慢或太笨重,那么我可能会切换到sqlite,它现在包含在Python(2.5)标准库中.
我不认为SQLite的将是"矫枉过正" - 它带有标准的Python 2.5以来,因此无需安装的东西,它可以使和处理在内存或本地磁盘文件的数据库.真的,怎么会更简单......?如果你想要内存中的所有内容,包括初始值,并希望使用dicts来表达那些初始值,例如......:
import sqlite3
db = sqlite3.connect(':memory:')
db.execute('Create table Users (Name, Location, Type)')
db.executemany('Insert into Users values(:Name, :Location, :Type)', [
dict(Name="Mr. Foo", Location="Boston", Type="Secondary"),
dict(Name="Mr. Bar", Location="New York", Type="Primary"),
dict(Name="Mr. Quux", Location="Chicago", Type="Secondary"),
])
db.commit()
db.row_factory = sqlite3.Row
Run Code Online (Sandbox Code Playgroud)
现在你的记忆中的小"db"已经准备好了.当然,在磁盘文件中创建数据库和/或从文本文件,CSV等中读取初始值并不困难.
查询特别灵活,简单和甜蜜,例如,您可以随意混合字符串插入和参数替换...:
def where(w, *a):
c = db.cursor()
c.execute('Select * From Users where %s' % w, *a)
return c.fetchall()
print [r["Name"] for r in where('Type="Secondary"')]
Run Code Online (Sandbox Code Playgroud)
发出[u'Mr. Foo', u'Mr. Quux'],就像更优雅但相当
print [r["Name"] for r in where('Type=?', ["Secondary"])]
Run Code Online (Sandbox Code Playgroud)
和您想要的查询只是:
print [r["Name"] for r in where('Location="Boston" or Type="Primary"')]
Run Code Online (Sandbox Code Playgroud)
等严重 - 什么不喜欢?
| 归档时间: |
|
| 查看次数: |
13677 次 |
| 最近记录: |