我有一个非常大的名单'data',我需要回答相当于
的查询if (x in data[a:b]):
表示a,b和x的不同值。
是否可以预处理数据以快速进行这些查询
答案 0 :(得分:4)
您可以创建dict
。对于每个元素存储它出现的位置的排序列表。
要回答查询:二元搜索大于或等于a
的第一个元素,检查它是否存在且小于b
预处理:
from collections import defaultdict
byvalue = defaultdict(list)
for i, x in enumerate(data):
byvalue[x].append(i)
查询:
def has_index_in_slice(indices, a, b):
r = bisect.bisect_left(indices, a)
return r < len(indices) and indices[r] < b
def check(byvalue, x, a, b):
indices = byvalue.get(x, None)
if not indices: return False
return has_index_in_slice(indices, a, b)
如果我们假设O(log N)
和list
具有O(1)“按索引获取”复杂度,则每个查询的复杂度为dict
。
答案 1 :(得分:1)
是的,您可以将这些切片预处理成集,从而使成员资格查找O(1)
而不是O(n)
:
check = set(data[a:b])
if x in check:
# do something
if y in check:
# do something else
答案 2 :(得分:0)
将列表放在数据库中,并利用内置的索引,优化和缓存。例如,从PostgreSQL手册:
创建索引后,无需进一步干预: 系统会在修改表时更新索引,它会 当它认为这样做会更多时,在查询中使用索引 比顺序表扫描更有效。
但是你也可以使用sqlite来简化(以及Python标准库中的可用性)。来自Python's documentation, regarding indexing:
Row实例用作Connection的高度优化的row_factory 对象。它试图模仿大部分功能中的元组。
它支持按列名和索引,迭代, 表示,相等测试和len()。
在该页面的其他地方:
Row提供基于索引和不区分大小写的基于名称的访问 到几乎没有内存开销的列。它可能会更好 比你自己的自定义基于字典的方法甚至基于db_row 溶液