存储(非可变)格式数据的最佳方法是什么:
doodahs = {
0-256: "FOO",
257: "BAR",
258: "FISH",
279: "MOOSE",
280-65534: "Darth Vader",
65535: "Death to all newbies" }
我有相对大量的这类数据集,所以我可以定义字典的方式(或接近它)并通过索引访问。
哦,这是在Python 2.4上,所以如果你想让我使用更新的版本,那么请给出非常好的升级理由(我会选择3:)
答案 0 :(得分:5)
我将范围拆分为元组,然后在课堂内,将项目保存在有序列表中。您可以使用bisect模块进行插入O(n)和查找O(logn)。
如果要将字典转换为新类,则可以构建无序列表并在最后对其进行排序
doodahs = [
(0, 256, "FOO"),
(257, 257, "BAR"),
(258, 258, "FISH"),
(279, 279, "MOOSE"),
(280, 65534, "Darth Vader"),
(65535, 65535, "Death to all newbies")]
您的__getitem__
可能会起到以下作用:
def __getitem__(self, key):
return self.doodahs[bisect.bisect(self.doodahs, (key,))]
__setitem__
可能是这样的:
def __setitem__(self,range,value):
bisect.insort(self.doodahs, range+(value,))
答案 1 :(得分:2)
如果你的整数的上限小于几百万,那么你只需将范围扩展为单个值。
class RangedDict( dict ):
def addRange( self, iterator, value ):
for k in iterator:
self[k]= value
d= RangedDict()
d.addRange( xrange(0,257), "FOO" )
d[257]= "BAR"
d[258]= "FISH"
d[279]= "MOOSE"
d.addRange( xrange(280,65535), "Darth Vader" )
d[65535]= "Death to all newbies"
您的所有查找都有效,并且是即时的。
答案 2 :(得分:1)
鉴于您的密钥中没有任何“缺口”,为什么您只是不存储每个分段的开头,然后像建议的那样使用bisect查找?
doodahs = (
(0, "FOO"),
(257, "BAR"),
(258, "FISH"),
(279, "MOOSE"),
(280, "Darth Vader"),
(65535, "Death to all newbies")
)
答案 3 :(得分:0)
class dict2(dict):
def __init__(self,obj):
dict.__init__(self,obj)
def __getitem__(self,key):
if self.has_key(key):
return super(dict2,self).__getitem__(key)
else:
for k in self:
if '-' in k:
[x,y] = str(k).split('-')
if key in range(int(x),int(y)+1):
return super(dict2,self).__getitem__(k)
return None
d = {"0-10":"HELLO"}
d2 = dict2(d)
print d,d2,d2["0-10"], d2[1]